5 ms·
I have some of my opinions about how it should do. > Uninitialized variables The compiler should be allowed to do one of: 1. Assume any arbitrary value, as l
by zzo38computer 3y ago
I have some of my opinions about how it should do.
> Uninitialized variables
The compiler should be allowed to do one of:
1. Assume any arbitrary value, as long as it remains consistent until a new value is assigned (which might or might not depend on the previous value). (However, the exact value need not be known at compile-time, and might not even be known at run-time if the program doesn't care about the exact value (in the example if the loop is removed then the exact value doesn't matter at run-time). It might be different every time the program runs.) Removing the loop in the example is valid; it would also be valid to start at a negative number (since you did not specify an unsigned type), but if for example you declare i before the loop instead of inside and then you add printf("%d\n",i); after the loop, then the program is required to print a number which is at least 10 and can fit in the int type; if standard library optimizations are enabled then it would be allowed to e.g. replace it with puts("42"); instead (but if the loop is not removed, then the number printed by this must be 10).
2. Read the value from a register or memory which is then used as the storage for that variable (for whatever time it needs to, just as though it was given a value which was returned from a function with no side-effects), but without initializing it.
3. Do whatever the target instruction set does (which seems very unlikely to me to do anything other than the above).
> Arithmetic overflow
The C specification should specify two's complement (it is the only good representation of integers anyways). Fortunately GCC has -fwrapv and -ftrapv, and I often use -fwrapv to avoid problem with signed overflow.
> Infinite loops
There is a rationale with some sense, but maybe better would be nevertheless not optimizing out the loop entirely like that. However, if standard library optimizations are enabled then it should be allowed to replace the loop with:
for(;;) pause();
> Null pointer usage
In this case, the program should just actually attempt to read, write, or call the null address, which should result in a segfault or other run-time error if possible (instead of being optimized out). However, the compiler is allowed to assume that such a call can never return, if it wishes (whether or not that is actually true on the target computer).
In the case of a read or write that is not marked as volatile, the compiler may substitute any value for a read and may optimize out a write, although it does not have to; it may also do what is specified above.
However, the optimization shown in the article should be allowed if Do is a local variable which is uninitialized, rather than being initialized as null. (You can disable optimizations (or possibly change some options) if you don't like that.)