4 ms·
There is such flags as -fwrapv which I use in programs that I think may need it. Maybe, there should be another flag which defines or partially defines many mo
by zzo38computer 5y ago
There is such flags as -fwrapv which I use in programs that I think may need it.
Maybe, there should be another flag which defines or partially defines many more things. For example, shift amounts out of range might produce any numerical answer (without other side effects), or it might trap once that operation is reached and not give any answer at all, but not demons in your nose or anything like that; either way, the compiler might or might not display a warning message. This is similar to what is mentioned in the linked document.
Another alternative flag might be used to guarantee terminating with an error message in such a case, making the program execute more slowly (because the compiler will insert such a check), for testing purposes perhaps. The document linked mentions such a case, but I think that it should not be the default case.
If you have:
int x[3];
int*y=x+1;
int*z=x-1;
Then, what I think is how it should work, should be:
- The program itself is valid.
- The pointers y and z are unequal; if you write y!=z then it is guaranteed to be true.
- Reading or writing through z should be considered as undefined behaviour and not allowed. The compiler can optimize based on the assumption that it doesn't happen, unless that optimization is disabled, or if the program is changed to specify it as volatile (in which case it remains undefined behaviour, but the compiler can no longer assume this when optimizing).
- Since z is out of range, comparing if it is less or greater than y is not predictable.
- Since z is out of range, there is no guarantee that it is
unequal to any other pointer that isn't based on x, including null; it might or might not be null.
- If you write z+=2 then z is now in range and z==y is true and you can read/write through z now.
If you write:
static int f(void) {
int a;
return a;
}
int main(int argc,char**argv) {
int x=42;
x=f();
printf("%d\n",x);
printf("%d\n",x);
printf("%d\n",x);
return 0;
}
Then it should be: The return value of f() will be some value for each call (not necessarily the same every time), and can optimize it. Since the function does nothing, and the return value is not defined, it is allowed to optimize out the reassignment to x and always print 42, or it can set x to some other value, which is unpredictable and not necessarily the same every time, but not print three different numbers, trap, or do other stuff. If standard library optimizations are enabled (which they might be by default, depending on the compiler), it may optimize out the entire program and replace it with a constant string and printing it, as long as it is a number and line feed, repeated three times with the same number, which must be in range of the int type. It may also compile the program like it is and when the program is executed multiple times, print different numbers different times, but always three same numbers. Printing nothing is not allowed, since the %d format specifier can never result in nothing; it always results in at least one digit.