8 ms·
> Improvements to C would be things like removing "undefined behavior" This nonsense again. I don't get this "undefined behavior" cliche. It seems it became fa
by geezerjay 9y ago
> Improvements to C would be things like removing "undefined behavior"
This nonsense again. I don't get this "undefined behavior" cliche. It seems it became fashionable for some people to parrot it like a mantra as a form of signaling. Undefined behavior just refers to something that is not covered by the international standard, and therefore doesn't exist nor should be used, but an implementation may offer implementation-specific behavior.
- blackguardx 9y agoI think many people overlook that "undefined behavior" mainly limits portability. Invoking undefined behavior won't cause your program to do random things, it just might not do the same thing when you switch to a different compiler. This is still a big problem, but not as big as people make it out to be, in my opinion. I think undefined behavior problems in the standard could be fixed, but compilers would need special flags for backwards compatibility with programs that rely on it.
- aw1621107 9y ago> "undefined behavior" mainly limits portability I had the impression that some things are UB because they can't specify a single behavior that would be efficient across all platforms C targets.
- fjsolwmv 9y agoNo that's implementation-defined. Undefined means code that is logically incorrect, but too expensive for the compiler/runtime to check and handle (reject) it. A simple example is array out of bounds access. It's too expensive to demand the compiler prevent it or guarantee to trigger some kind of signal at runtime. But if you are willing to pay the cost , you can use a language or compiler that is safer and promises to throw an exception or provides safe statically sizd arrays
- UncleMeat 9y ago> Invoking undefined behavior won't cause your program to do random things According to the spec, it literally can. The compiler is free to replace your entire program with unrelated functionality. It can ever do a different thing each time it compiles the program. There are implementation specific behaviors (# of bits in a char), which are different.
- deleted 9y ago[deleted]
- khedoros1 9y agoUndefined behavior is undefined even using the same version of the same compiler. If it does produce the same repeatable behavior, consider it luck. Implementation-defined behavior limits portability in the way you describe, but UB's not the same thing. IB should behave the same way in the same implementation. UB doesn't have to.
- knome 9y agoImplementation defined behavior is not the same thing as undefined behavior. Undefined is out of the scope of the language entirely. Using a non-existent index into an array, for example. While you might reasonably expect the program will just look past the end, there is not guarantee it will do so. Optimizing compilers, in particular will assume such a thing cannot happen, and can assume a code branch that does something like this is impossible to reach and discard it entirely. No one will "fix" such an optimization bug, because the code behind it is valid for ASTs that may have been put into that form from conforming code generated by macros and branches that wouldn't be called. There's nothing to fix. You're telling it to do something impossible, and it's assuming it can't happen.
- msla 9y agoThere's also behavior which is undefined for hardware reasons. An example is what the C standard calls "trap representations": Bit patterns which fit into the space occupied by a specific type, but which will cause a hardware trap (exception, interrupt, what have you) if you actually store them in a variable of that type. The only type which cannot have trap representations is unsigned char. Basically, what it amounts to is this: C compilers don't compile to a runtime, they compile to raw machine code with, perhaps, a standard library. If you do something the hardware doesn't like when your program runs, well, the C compiler is long gone by that point and the C standard makes no guarantees. More prosaically, storing to a location beyond the end of an array might not cause a segfault. It might corrupt some other array, it might cause a hardware crash, it might even corrupt the program's machine code. Because C is explicitly a language for embedded hardware, with no MMUs, no W^X protection, and no OSes, the C standard can say very little about such things.
- tlb 9y agoYou're mixing up "undefined behavior" and "implementation-defined" behavior. Implementation-defined behavior is fine. "Undefined behavior", as the term is used in the C spec, means that literally anything can happen. The compiler is allowed to assume that UB never happens, so if it does the program can produce random results. See http://en.cppreference.com/w/cpp/language/ub http://en.cppreference.com/w/cpp/language/ub
- geezerjay 9y ago> You're mixing up "undefined behavior" and "implementation-defined" behavior. Implementation-defined behavior is fine. "Undefined behavior", as the term is used in the C spec, means that literally anything can happen. Actually I didn't. My point was rather obvious: the whole point of the standards specifying UB is precisely to let implementations define the behavior themselves.
- aw1621107 9y ago> let implementations define the behavior themselves That's literally the definition of implementation-defined behavior. Undefined behavior really means undefined; in terms of the C language, there are no constraints on behavior. Sure, you might get a result one way on one implementation, but if you rely on that you're technically writing a dialect of C, and need to let the compiler know using flags.
- UncleMeat 9y agoImplementation defined behavior does the same thing for a given implementation. The compiler can produce totally different code every time you compile a program with UB. It can even affect code that is totally unrelated to the UB.
- mattkrause 9y agoI'm not sure I buy that second part. Legalistically, I guess it could (the behavior isn't defined, after all), but typically the optimizer makes some valid-only-if-the-code-is deductions and things snowball from there....
- derefr 9y agoWhen people talk about "removing undefined behavior", they usually mean requiring that compile-time-detectible undefined behaviors be converted into explicit errors. For example, there are quite a few people who would like to see a C where you can't actually write this: // int x, y; if(++x < y) { ... } ...because, well, the behavior of integer overflow is undefined in C, so that code could technically do anything, even though it seems perfectly innocent, especially when coming from a checked language. Of course, you can't do anything in the C standard to require that this code work as-is, because the C standard applies to architectures where mutually-exclusive things happen under integer overflow. But you can always just disallow it completely, and require that people use intrinsics that are explicit about what overflow behavior they expect (where that behavior reduces to plain output on target architectures that follow it, and to a shim on target architectures that don't. You know, like floating-point support, or atomics.)
- geezerjay 9y ago> they usually mean requiring that compile-time-detectible undefined behaviors I don't believe that's the case for plenty of reasons, such as: - compilers already do that ( yeah, it's one of those RTFM things. See for example GCC's undefined behavior sanitizer) - the standard already specifies exactly what it is left undefined, thus it's a compiler-related issue (see point above) Let's face it: some people mindlessly parrot the"undefined behaviour" mantra just for show.
- derefr 9y ago> compilers already do that ( yeah, it's one of those RTFM things) I believe 99% of what people care about the C standard doing, re: UB handling, is requiring compilers to make certain behaviours the default, rather than hidden behind different flags that C newbies who don't understand UB (who thus code most of the bad C!) won't ever set.
- jcelerier 9y ago> - compilers already do that ( yeah, it's one of those RTFM things. See for example GCC's undefined behavior sanitizer) well, no they don't. UBSan is at run-time because most UB is impossible to catch at compile-time.
- tytytytytytytyt 9y agoOr it's something undesirable and you parroting back the definition of UB doesn't add anything.
- sedachv 9y ago> I don't get this "undefined behavior" cliche. The problem is that you can do everything in portable C that you can do with undefined behavior in C, and often in a more straightforward fashion.[1] The compiler won't tell you that you are doing it wrong; there are many examples, tutorials, and books that encourage you to do the wrong thing. The undefined behavior will work until you switch to a different system. Why allow the wrong thing to continue to happen? [1] A very good example of this is endianness: https://news.ycombinator.com/item?id=16189110 https://news.ycombinator.com/item?id=16189110 https://commandcenter.blogspot.se/2012/04/byte-order-fallacy.html https://commandcenter.blogspot.se/2012/04/byte-order-fallacy...
- fjsolwmv 9y agoYou are conflating undefined with implementation defined. If you use undefined behavior the compiler might simply delete your code since it's not defined.
- sedachv 9y agoYou and a lot of people in this discussion seem confused the other way. The amount of things in C that are implementation-defined is relatively small and most has to do with character encodings and byte size (storage unit). The kind of behavior people are pointing to is definitely labeled as undefined, and there is a lot of it. Take a look at Harbison and Steele for example.
- userbinator 9y agoI've noticed the same thing. A strongly adversarial relationship between compiler writers and users, justified by religious adherence to The Holy Standard and a complete lack of understanding of how people actually want and expect the language to behave in practice. Undefined behavior just refers to something that is not covered by the international standard, and therefore doesn't exist nor should be used, but an implementation may offer implementation-specific behavior Indeed. Even the standard itself, to quote its definition of undefined behaviour (emphasis mine): "behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements 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)." The fact that the standard "imposes no requirements" should not be taken as carte blanche to completely ignore the intent of the programmers and do entirely unreasonable things "just because you can", yet unfortunately quite a few in the compiler/programming language community think that way. It's why I'm very encouraging of more programmers writing their own compilers and exploring new techniques, to move away from that suffocating and divisive culture. Compilers should be helping users, not acting aggressively against them just because it's allowed by one standards committee.
- pjmlp 9y agoThe thing is that you only see this compiler writer culture among C and C++ devs. Other language communities that put correctness before performance at any cost, don't share this mentality, including the compiler writers.
- kbenson 9y agoI'll just refer you to a comment I wrote last week, which I covers a specific case where undefined behavior and how a compiler chose to handle it caused a security problem in Cap'N'Proto.[1] I think it's about as condensed as I've seen it explained, while linking to further information. 1: https://news.ycombinator.com/item?id=16596409 https://news.ycombinator.com/item?id=16596409