5 ms·
Yes, by having the NULL check after those members have been accessed, you're telling the compiler that vc cannot be NULL (because accessing the members if vc is
by vinkelhake 13y ago
Yes, by having the NULL check after those members have been accessed, you're telling the compiler that vc cannot be NULL (because accessing the members if vc is NULL would be undefined behavior). The compiler can (and GCC will) eliminate the NULL check completely.
- ghswa 13y agoDoes gcc make any kind of assumptions about signed-overflow? For example, would it eliminate the comparison in this code: int8_t i; /* ... */ i += 1; if (i == 0) { /* ... */ }
- vinkelhake 13y agoYes, it'll exploit the fact that signed overflow is undefined. int incr(int i) { int old = i; i += 1; if (i < old) return 1; return 0; } GCC optimizes this to 'return 0;'. EDIT: Updated to a better example.
- silentbicycle 13y agoWould you mind elaborating on that? I don't see this behavior with GCC 4.2.1 on OSX or OpenBSD at -O3 when I look at the disassembly.
- vinkelhake 13y agoHere's the simplest example I could come up with (it's functionally equivalent to the code OP pasted): int zero1(int* i) { *i = 0; return 0; } int zero2(int* i) { *i = 0; if(i == 0) return 1; return 0; } GCC produces the same code for these two functions. If the 'if' in zero2 is moved to the top of the function, it takes effect. I tried this on GCC 4.8.1. A wonderful site for checking these things is: http://gcc.godbolt.org/ http://gcc.godbolt.org/
- silentbicycle 13y agoExcellent, thank you. Those also compile differently for me, so it probably appeared in a newer version of gcc.
- throwaway_yy2Di 13y agoIt's an optimization, it shows up at -O2.
- dkersten 13y agoWhy put the if in at all then? Regardless of optimisation, it will never be followed - it segfaults if NULL and returns normally if not.
- deleted 13y ago[deleted]
- throwaway_yy2Di 13y agoThis works. Also it does this without a notice, even when I ask for -Wall. I found you can control this with -f{no-,}delete-null-pointer-checks. Apparently it's enabled by -O2. http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Optimize-Options.html#index-fdelete-null-pointer-checks-785 http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Optimize-Options...
- signa11 13y agohuh :) have you actually tried doing that i.e. call the function with NULL params and see ? you will see a segfault. anyways, rather than rely on vagaries of -O2 implementation on compilers, i would rather be explicit about it and just assert invariants...
- vinkelhake 13y agoI believe you got my comment completely bass ackwards. I'm not describing some optimization that you, the programmer, can do. I'm talking about what the compiler can (and will) do by assuming your code doesn't have undefined behavior. In this particular case, the compiler recognizes that if the pointer is NULL, undefined behavior has already been invoked and it can therefore eliminate the check. I recommend this series of posts on the LLVM blog: http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html http://blog.llvm.org/2011/05/what-every-c-programmer-should-...
- signa11 13y ago> In this particular case, the compiler recognizes that if the pointer is NULL, undefined behavior has already been invoked and it can therefore eliminate the check. ah, makes sense thank you !
- EpicEng 13y ago*you will see a segfault* No, you will see undefined behavior. Undefined behavior doesn't mean "you get a segfault". That would be defined behavior.
- fit2rule 13y agoRelying on the compiler is not the way to produce safe code.
- vinkelhake 13y agoWe're in violent agreement. I am preaching that you should code to the standard, not implementations. See my reply to 'signa11'.