6 ms·
The article quoted someone saying "OUCH. So, basically, people have been depending on C undefined behavior for ages..." This doesn't actually have to do with c
by uxp100 7y ago
The article quoted someone saying "OUCH. So, basically, people have been depending on C undefined behavior for ages..."
This doesn't actually have to do with c undefined behavior at all right? I think I get what is happening but that comment is throwing me off.
- deleted 7y ago[deleted]
- quietbritishjim 7y agoAs I understand it, some C programs omit the final argument to a function. That function does not actually read the value of the argument, but it is still undefined behaviour for it not to be passed in.
- wahern 7y agoYes and no. This is great example of why some of the rhetoric about undefined behavior in C is misleading. This is fundamentally an FFI issue. The C compiler is relying on the function signature declared, explicitly or implicitly, by the person writing the binding code. But this declared signature is wrong, and because it's wrong C says that the behavior when invoking the routine is undefined--undefined behavior. Other languages would have the exact same result. If you told Rust that the FFI prototype for a FORTRAN routine was foo(pointer-to-char) instead of foo(pointer-to-char, size_t), you'd get the exact same broken runtime behavior as with the C code. But Rust never defines this as "undefined behavior". Rust's behavior is no less undefined in the practical sense, it just don't formalize the concept in its specification, such as it is. Like most languages it side steps the issue because it's a thorny area for a specification, especially thorny now that the literal phrase "undefined behavior" elicits reactionary flames from the peanut gallery. If you say nothing you're not inviting criticism, nor are you burdened with managing yet another dimension of consistency in your specification. There are problems with "undefined behavior" in C, how it works in the standard and especially how compilers use it to shift blame for insecure semantics. The problems are just nuanced and technical and can't be constructively discussed outside specific contexts. And especially in discussions comparing C to different languages, these problems get conflated with orthogonal issues like type safety. EDIT: For context here are some relevant citations to C11 itself: C11 (N1570) 3.4.3p1: "undefined behavior [is] behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements" C11 (N1570 3.4.3p2: "NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message)." C11 (N1570) 4p2: "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’’."
- perl4ever 7y ago"that the literal phrase "undefined behavior" elicits reactionary flames from the peanut gallery" The issue I have with "undefined behavior" is that defining undefined behavior is like dividing by zero. It's like saying you have proven the efficacy of the placebo effect. Once you start believing in contradictions, you are on the road to hell. There is an immeasurable difference between what you say Rust does, leaving undefined behavior undefined, and trying to have it both ways.
- wahern 7y agoThere's exactly 1 implementation of Rust. Rust is whatever HEAD in the Rust repository implements. C was standardized nearly 20 years after the first C compiler. The original C standard and its revisions were written in a way that (with some exceptions and caveats) effectively christened existing implementations and codebases as "C", just not necessarily in their entirety. The guiding principle has always been to iteratively formalize and evolve existing practice. If a standard were to effectively tell any compiler or project that wasn't line-for-line "conformant" or "correct" or "strictly conformant" to GTFO, the C standard would have failed in bringing order to chaos. The use of "undefined behavior" was and remains a mechanisms for achieving that goal. C isn't trying to "have it both ways"; it's addressing real, substantial dilemmas within a huge software ecosystem. C's approach is somewhat unique and idiosyncratic, but rooted in a historical context that cannot be ignored. And it's success is undeniable. Some languages, like Rust, with only a single well-accepted implementation have the luxury of staying silent. Other languages (e.g. Ada, once upon a time) with diverse, equally relevant implementations that use a heavier hand in directing the evolution have a poor track record. You can't force a vendor to implement some behavior if they don't want to; and if you attempt to coerce them they're liable to walk away. C++ is another somewhat unique case, but while there remains substantial diversity of C compilers that are as a practical matter functional C11 implementations (C11 made alot of C99 optional), there are now effectively only two relevant C++ compilers: GCC and clang. (Maybe Visual Studio, we'll see.) Step back and consider why C remains so popular and successful despite its obvious and well acknowledged faults. People think it's an accident of history that C has been so influential, but I think that's self-serving. It's much easier to say that than to acknowledge that the evolution of C reflects an uncomfortable reality in the technology industry regarding the forces that lead to success and failure. Node.js and PHP reflect some similar uncomfortable truths. C's concept of "undefined behavior" is an attempt to cabin and grapple with some of those realities in an honest and more intellectually rigorous manner. That's why it's so easy to pick on "undefined behavior" in C; its whole function is to help outline the contours of and acknowledge some very deep pathologies rather than ignoring them or pretending they don't exist. Rust's unsafe{} is loosely similar, but you can't directly compare the two because both the historical and contemporary contexts are different. Again, there's precisely 1 Rust implementation; it doesn't need to formalize undefined behavior in a way that permits reconciling diverse behaviors (behaviors that are often justifiably relied upon) and providing a path to better, safer, unified semantics. Rust developers can ignore various matters of undefined behavior until one day it can dictate the One True Way, without risk of splitting the community or making itself irrelevant.
- deleted 7y ago[deleted]
- kazinator 7y agoISO C specifies no requirements for interacting with Fortran. Every aspect of this is "C undefined behavior". Requirements are violated, to be sure, but not ones coming from ISO C.
- uxp100 7y agoThat doesn't sound like undefined behavior to me. Or at least a different definition than the normal one.
- kazinator 7y ago"C undefined behavior" is the status of the behavior of a C program for which a requirement cannot be found in ISO C by omission, or for which ISO C explicitly says that it's not giving a requirement. No requirement can be found in ISO C for linkage with Fortran. There is another "undefined behavior" which is the informal situation that happens when a behavior is not defined by anyone at all: not ISO C, not the platform's ABI or API's, not the compiler reference manual. (That is hard to pin down, because what does it mean? If I compile a program, it's always defined by whatever the object code is doing. We can interpret the instructions through the architecture reference manual, and if we don't find a problem then, hey, it's defined! (However, the compiler's documentation doesn't guarantee the consistency of always producing that particular compiler output for that program.) In any case, that Bugzilla comment specifically said "C undefined behavior".