3 ms·
> The code in question is not valid C code. If it were not valid C code, then a standard-compliant C compiler would be required to reject it. Now don't get me
by mnarayan01 14y ago
> The code in question is not valid C code.
If it were not valid C code, then a standard-compliant C compiler would be required to reject it.
Now don't get me wrong, having code that is dependent dereferencing past the end of an array is not a good idea. Having such code in a popular benchmark is a bad situation to be in, particularly when it interferes with progress in compiler optimization. It is not, however, "illegal" for any standard definition of illegal, and in this context clarity is important as ambiguity can interfere with compiler optimization :)
Edit: Assume you have a machine/OS with a page size of 1 byte. Can a compiler generate a program that does not raise an exception in the situation mentioned by the OP? Saying such a program is illegal would surely imply that it could not.
- mikeash 14y ago> If it were not valid C code, then a standard-compliant C compiler would be required to reject it. Nope! Here's a direct quote out of the copy of the standard I have lying about, from the section that discusses when diagnostic output is required: "The intent is that an implementation should identify the nature of, and where possible localize, each violation. Of course, an implementation is free to produce any number of diagnostics as long as a valid program is still correctly translated. It may also successfully translate an invalid program." That last sentence is particularly pertinent. Many (most?) languages have two kinds of programs: valid and invalid. C has three: valid, invalid requiring the compiler to reject it, and invalid but the compiler may still accept it. For whatever reason, people have a very hard time understanding the implications of the third category, or, as in your case, even realizing that it exists.
- mnarayan01 14y agoIs that C89 or C99? I only see that in the latter, though the C89 spec I see may have footnotes removed. From C99: > A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined. would seem to imply that a standard compliant compiler would need to produce a message for an invalid program. I will say it is both interesting and surprising (to me) that at least C99 does allow for the successful translation of an invalid C program. Regardless, while informative, I'll probably stop posting on this topic before I lose the ability to ;)
- mikeash 14y agoYour quote is where the footnote comes from. I think what you're missing (and what I missed when I first read that while looking this up) is the "violation of any syntax rule or constraint" part. In other words, a diagnostic is required for syntax errors only. For other stuff, like bad pointer dereferences, division by zero, etc., it's optional.
- mansr 14y agoThat is how it has to be. Determining at compile-time whether a given program will invoke undefined behaviour at runtime is equivalent to solving the halting problem, which we know is impossible.
- mikeash 14y agoNot sure which way you mean it, but it's important to note that this is only true if you have C-like undefined behavior in your language, and is not true of computer languages in general. It's not all that hard to define the results of all operations. I believe a lot of languages (e.g. Java) do this. For example: - C makes it undefined to access beyond the end of an array. It's possible to define this as always throwing an exception or terminating the program. - C makes it undefined to overflow a signed integer type. We can define this as following two's complement rules, or terminating the program. - Writing to a constant string is undefined. We can define this to always work, to always terminate the program, or we can even define a type system that makes it impossible to even try. Once you define all behavior like this, then there is no undefined behavior. A valid program is one that your compiler accepts, no more and no less. The program can still have bugs, of course, but if the program compiles, its output is always well-defined.
- mansr 14y agoThis entire thread is specifically about C.