Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Why yes. This is undefined behavior:

  int main(void)
  {
     char buf[256];
     read(0, buf, sizeof buf);
  }
The translation unit doesn't define a read function anywhere, and it's not in ISO C.

Suppose that we translate this unit and link it to make a program.

There are two possibilities: (1) the program fails to link due to the unresolved reference. (2) it actually links, producing an executable.

Under (2) the behavior is undefined.

The POSIX read is a documented extension that stands in the place of undefined behavior.

Libraries have to allow the ISO C program to define a function called read because the language doesn't reserve the identifier.

The GNU C library makes read a weak symbol, aliasing to __libc_read.

Internally, it calls __libc_read, so that it doesn't break if the application redefines read.

So ISO C undefined behavior is a big area. It contains documented extensions like <unistd.h> and read, well as null pointer dereferences, divisions by zero, out-of-bounds access, double free, ...

> I was not aware of this.

You might want to keep it to yourself though, if you don't want downvotes.



> A program that is correct in all other aspects, operating on correct data, containing unspecified behavior shall be a correct program and act in accordance with 5.1.2.3.

With your interpretation of undefined behavior, there cannot be any correct program containing #define, #include or (non-library) function calls. This is obviously absurd.

The C standard, as any other written text, is ambiguous in certain places and requires interpretation. I am not a language lawyer, but I think your reading of "by the omission of any explicit definition of behavior" is too broad to be useful and it's very likely not what the C standard people intended. It's funny, though!

> You might want to keep it to yourself though, if you don't want downvotes.

Why? I'm happy to admit when I am wrong or learned something.

EDIT unspecified -> undefined


I'm not aware that I gave an interpretation of unspecified behavior. That is different from undefined behavior.


That was obviously a typo. C'mon.


I don't follow. What is a typo? Whose typo? I see that exact text as far back as C99 (in 4 Conformance) "A program that is correct in all other aspects, operating on correct data, containing unspecified behavior shall be a correct program and act in accordance with 5.1.2.3."


> I don't follow. What is a typo? Whose typo?

My second paragraph did contain a typo ("unspecified" instead of "undefined") which I have fixed (see EDIT).

> "A program that is correct in all other aspects, operating on correct data, containing unspecified behavior shall be a correct program and act in accordance with 5.1.2.3."

In conjuction with the preceding passage about undefined behavior, I read this as follows: Any program that does not violate ‘‘shall’’ or ‘‘shall not’’ requirements, does not contain undefined behavior and operates on correct data is a correct program; it may, however, contain unspecified behavior. How would you read this instead?

Back to 4 ("Conformance"):

> [...] Undefined behavior is otherwise indicated in this International Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition of behavior. [...]

What is an explicit definition? It just isn't possible to completely define any phenomenon down to the smallest detail, so one can always come up with a case that isn't "explicitly defined". IMHO this passage is a mistake in the standard.


The purpose of that sentence is not entirely clear to me. It seems to be defining the term "correct program", but hasn't given the term in italics, and the term is not used anywhere. Most C programs contain unspecified behavior because, for example, the order of evaluation of function arguments is unspecified. If we call any function of two or more arguments, unspecified behavior has occurred. Usually, there is no visible difference, so it doesn't matter. It's not clear to me why that sentence includes unspecified behavior, but not implementation-defined. I think it may be intended to include implementation-defined, since implementation-defined behavior is "unspecified behavior where each implementation documents how the choice is made".

In any case, it's saying that nonportable programs can be correct. Later in another paragraph, a strictly-conforming program concept is defined which cannot produce output dependent on implementation-defined or unspecified behavior. Those behaviors themselves cannot be eliminated (like unspecified evaluation orders) but the program doesn't produce any output dependent on them.

Note that although #include <unistd.h> is defined by implementations, it is not "implementation-defined behavior". It is a documented extension. The same section talks about extensions a little down "A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any strictly conforming program."

An explicit definition is where the standard gives a requirement in words. I think the word "explicit" is there just for emphasis. Definitions are explicit. Explicit is the opposite of implicit; implicit means understood without words. You can't define something without words. Maybe the purpose is to discourage implementors and users from making tenuous inferences of unwritten definitions of behavior.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: