3 ms·
Could it be that you're confusing "undefined behavior" with "implemented-defined behavior"?
by spacechild1 3y ago
Could it be that you're confusing "undefined behavior" with "implemented-defined behavior"?
- kazinator 3y agoNo, it coudln't. If you think so, find the chapter and verse in ISO C which says that implementors must choose a behavior for #include <unistd.h> and document it ("implementation-defined") or without being required to document it ("unspecified"). Can you prove that a conforming implementation of any version of ISO C, from the standard alone, may not segfault or wipe storage device as a result of #include <unistd.h>? (I.e. that if that were to happen, the implementation would be nonconforming?) When a POSIX implementation gives you #include <unistd.h>, it is "behaving in a documented manner characteristic of the implementation": one of the possible ways that undefined behavior plays out!
- spacechild1 3y agoI have to admit that your original post confused me. Why exactly do think that #include <unistd.h> is undefined behavior? Here's what the C11 standard draft says in 6.10.2 (source file inclusion): A preprocessing directive of the form # include <h-char-sequence> new-line searches a sequence of implementation-defined places for a header identified uniquely by the specified sequence between the < and > delimiters, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-defined. Seems pretty well-defined to me. EDITED to include C standard reference.
- kazinator 3y ago> Why exactly do think that #include <unistd.h> is undefined behavior? Because ISO C doesn't say what happens if the implementation finds something by that name, and replaces the #include directive with that content. A given system could have a unistd.h file which contains #pragma __self_destruct which causes the machine to melt down.
- spacechild1 3y agoThat's a bit silly. By that logic, every single macro - and every single non-library function call - would be undefined behavior as well. But in general you are right that undefined behavior does not necessarily have to be explicitly stated as such: > If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint or runtime-constraint is violated, the behavior is undefined. Undefined behavior is otherwise indicated in this International Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three; they all describe ‘‘behavior that is undefined’’. I was not aware of this.
- kazinator 3y agoWhy 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.
- spacechild1 3y ago> 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