5 ms·
Super, super pedantic point: that probably wouldn't happen with your example because most of the time, free is defined in a shared library somewhere else, and t
by scott_s 12y ago
Super, super pedantic point: that probably wouldn't happen with your example because most of the time, free is defined in a shared library somewhere else, and the compiler wouldn't be able to inspect its code. Even if it's in the same source file, most compilers don't optimize across non-inlined function boundaries.
But! You made a good point, and it would apply to a function that did a null-check which was inlined. It's easy for us to imagine a function which 1) does a null-check, 2) gets inlined, and 3) is used in places in the code which dereference the pointer before calling the function.
- mikeash 12y agoThe standard library thing is interesting. Modern compilers actually understand that stuff a lot. I don't think they'll reach into the implementation, but they understand the guaranteed semantics. For example, they know that this is undefined behavior: free(ptr); printf("after free, it contains %d\n", *ptr); And the nasal demons shall flow freely. The compiler will certainly know that there's a NULL check in there. However, the smarts are different enough that it will also know not to warn you about it. So, yes, this is an example that won't happen in reality, although there's no reason it couldn't.
- ygra 12y agoWhile compilers won't optimise functions they don't yet know about, they do know the standard library and the respective guarantees and constraints. This includes removing calls to memset for things that are never read again (horrible for passwords or keys in memory, which is why there is a SecureZeroMemory or related function in operating systems) or other things. As a somewhat trivial example: #include <stdio.h> #include <string.h> int main() { printf("%lu\n", strlen("Test")); return 0; } will get compiled by MSVC (with /O2) to ; Line 5 push 4 push OFFSET ??_C@_04OJNJKCBM@?$CFlu?6?$AA@ call _printf add esp, 8 ; Line 6 xor eax, eax ; Line 7 ret 0 The compiler knows about strlen and notices that there is no need at runtime to calculate the length of a constant string and just puts in the result.
- scott_s 12y agoGreat example, however this does not apply to free - or I would be very surprised if it did. It is relatively common for people to override malloc and free at runtime, so I would be very surprised if the compiler treated malloc or free as a compiler intrinsic, and inlined the code. I would not be surprised, however, if the compiler used the semantics of malloc or free to reason about the surrounding code. The original point, however, was about inlined code leading to generated code that no reasonable person would write (null check after use). So I still think that would not happen for free.
- mikeash 12y agoI just tested clang, and free(malloc(42)); gets completely optimized out, as does free(NULL);. free(argv) doesn't, so it's not quite that clever, at least.