Consider the following hypothetical type:
typedef struct Stack { unsigned long len; void **elements; } Stack;
And the following hypothetical macros for working with a type (purely to increase readability). In these macros, I assume that this argument is of type (Stack *), and not just Stack (I cannot worry about typing a _ Generic expression here.)
#define stackNull(stack) (!stack->len) #define stackHasItems(stack) (stack->len)
Why am I not just using !stackNull(x)
to check for elements on the stack? I thought it would be a little less efficient (read: not at all noticeable at all, but I thought it was interesting) than just checking stack->len
, because that would lead to double negation. In the following case:
int thingy = !!31337; printf("%d\n", thingy); if (thingy) doSomethingImportant(thingy);
The string "1 \ n" would be printed, and it would be impossible to optimize the conditional (well, in fact, only impossible if the thingy variable did not have a constant initializer or was changed before the test, In this case, we say that 31337 is not a constant), because (!!x)
guaranteed to be either 0
or 1
.
But I wonder if the compilers will optimize something like the following
int thingy = wellOkaySoImNotAConstantThingyAnyMore(); if (!!thingy) doSomethingFarLessImportant();
Will it be optimized for actual use (thingy) in the if statement, as if the if
were written as
if (thingy) doSomethingFarLessImportant();
If so, will it expand to (!!!!!thingy)
and so on? (however, this is a slightly different question, since it can be optimized in any case !thingy
is !!!!!thingy
regardless of, for example, -(-(-(1))) = -1.)
In the title of the question, I said โcompilersโ, which I mean that I ask if this compiler does any , however I am particularly interested in how GCC will behave in this case, since it is my choice compiler.