On 08/11/15 18:17, Vincent Lefevre wrote:
On 2015-11-08 16:14:56 +0100, David Brown wrote:
I got close with a dont_care() :
static inline int dont_care(void) {
int x;
asm ("" : "=r" (x) : );
return x;
}
This lets gcc "generate" an int without any instructions. But the compiler
doesn't know that you don't care what value it has, so this won't let the
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
compiler eliminate the conditional in :
int foo(int x) {
if (x < 1000) {
return x * x * x;
} else {
return dont_care();
}
}
I don't think that this is the problem here. First, the conditional
could be eliminated only if the code is in the x < 1000 case does not
have side effects (such as traps in case of overflow). Moreover, even
if the compiler knows that it is safe to do the transformation, would
it know that doing it would yield faster code? This is not obvious.
The compiler knows that the code in the "x * x * x" branch is without
side-effects or traps. It also knows that omitting the conditional
leads to smaller and faster code. But what it does not know, is if the
/asm/ instruction has side effects or not. That, I think, is why the
comparison is kept.
IMHO, the right thing to do is to have a way to instruct the compiler
that the multiplication has some defined behavior even in case of
overflow. Something like -fwrapv. However, the problems with -fwrapv
is that it is not part of the semantic of the code and that it is
global.
That would not help, as it is not the behaviour of the integer
multiplication that matters. (Changing to unsigned int, which has no
undefined behaviour on overflow, does not make a difference.)
Another option is:
static inline int dont_care2(void) {
int x = x;
return x;
}
But that sometimes ends up with an unnecessary setting of x to 0.
And this is also undefined behavior.
You are correct as far as I can see. gcc (and many other compilers) can
accept this syntax as a way of avoiding warnings about data that might
be used uninitialised, but actually /using/ the self-initialised
variable is undefined behaviour, I think.
So I am still searching for an unspecified, but not undefined, int
generator.