5 ms·
undefined behavior = the compiler has the right to do wathever it wants This is exactly what the C standard says. And yes, that is problematic, especially sinc
by kutkloon7 9y ago
undefined behavior = the compiler has the right to do wathever it wants
This is exactly what the C standard says. And yes, that is problematic, especially since there is no way to detect undefined behaviour. I consider this to be the main problem. If C compilers would simply check for undefined behaviour in the debug build, there would be a lot less problems.
- vertex-four 9y agoThe issue there is that you pretty much have to use undefined behaviour in C and certain low-level applications of C++. C is therefore a broken language IMHO, but... there we have it.
- jjnoakes 9y agoI don't think one ever has to rely on undefined behavior. If you think you do, you can usually rewrite your code to avoid it, or rely on implementation defined behavior for specific compilers. And if that is not low level enough, you should be using assembly.
- _pmf_ 9y agoThat's wrong. All firmware I worked with used assembly for early initialization (startup.s) in those cases where the only alternative would be to rely on UB. I've worked with firmware that only worked with -O0 and failed with -O2, but these were always bad implementations, not due to some inherent requirement to rely on UB (most common example: failing to recognize that using volatile does not guarantee a memory barrier).
- vertex-four 9y ago> I've worked with firmware that only worked with -O0 and failed with -O2 But as we can see in this vuln, there's functionality that works in the normal case but where important checks are elided, and compilers might decide not to do anything with a piece of undefined behaviour in one version but not in the next. Whether a piece of code works in -O2 doesn't prove it doesn't contain undefined behaviour.
- _pmf_ 9y ago> undefined behavior = the compiler has the right to do wathever it wants It would also be allowed to follow the principle of least surprise. Most instances of UB have a specific expected outcome; for signed overflow, one would probably expect the architecture specific signed overflow handling to happen. It's a bit paradox that some hard errors for which no such expected outcome exists, such as an address violation, can easily be caught by the programmer (SIGSEGV), but errors (UB) for which a specific, sensible reaction exists are not only silently tolerated, but actively exploited when searching optimization.
- wbl 9y agoIt's not actively exploited, just ignored when checking the optimization is valid. Putting values in loops into registers can require making assumptions about different types of pointers pointing to different things.
- GTP 9y ago>This is exactly what the C standard says. No, please read the page that I linked: there are historical reasons to believe that the meaning of undefined behavior is different.
- kutkloon7 9y agoI have read it. The rant does explicitly not quote the C standard, and instead informs us of how compilers should work according to the author. Historical context does not change the content of a standard. From the 2007 draft for the C99 standard[1]: "undefined behavior: behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements" [1] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
- GTP 9y agoThe International Standard imposes no requirement != The compiler can use flawed logic while making assumptions. By flawed logic I'm reffering to the argument "this situation is undefined so it never happens", in particular applied to the example of pointer dereferencing: when GCC see a pointer being dereferneced it instantly assumes that it isn't null, so if the programmer later explicitly checks for the value being not null GCC ignores it and doesn't translate that part of the program. This can introduce severe vulnerabilities only because the compiler is trying to do an optimization that I find too much aggressive: it decides not to compile an entire part of a program!
- lmm 9y agoWhat the compiler does in the face of undefined behaviour is out of scope for the standard, by definition. The problem is that the standard was written as a minimum that programmers could rely on even the worst compilers to implement, with the intention that compiler writers would come up with improvements that would then be standardised (the same way that happens with e.g. web standards). Instead compilers regressed to doing the minimum permitted by the standard.