- Does
sizeof((int[]){1,2,3})
get evaluated at compile time? And is guaranteed by the standard. - Does the sizeof operand in this case produce side effects?
I am asking this question because with Tasking compiler this line results in warning “side effects of ‘sizeof’ operand are ignored“.
I am wondering if this is a spurious warning or is there something to it.
I am trying to be compliant with MISRA rule 13.6 that states “The operand of the sizeof() operator should not contain any expression which has potential side affects”.
9
- Does
sizeof((int[]){1,2,3})
get evaluated at compile time? And is guaranteed by the standard.
The spec does not say, but probably so. This is in any case not directly relevant to MISRA 13.6
- Does the
sizeof
operand in this case produce side effects?
No, not as far as the spec is concerned. The expression (int[]){1,2,3}
produces a value when evaluated, but the language spec does not describe any side effects (producing a value is not itself a side effect). Contrast with i++
, which both produces a value and has a side effect of modifying the stored value of i
.
Note well that the operand is not evaluated at all, as other answers also observe, but that’s the point of the MISRA rule. It wants you to avoid sizeof()
operands that would have side effects if evaluated, because it may be surprising that the operand isn’t actually evaluated, and therefore the side effect does not occur.
I am asking this question because with Tasking compiler this line
results in warning “side effects of ‘sizeof’ operand are ignored“.I am wondering if this is a spurious warning or is there something to
it.
If MISRA is to be read as talking about side effects defined by the language spec then the warning is definitely spurious.
If MISRA were read as talking about side effects produced by a particular C implementation, including any not defined by the language spec, and if in your particular implementation, evaluating a compound literal did produce a side effect, then the warning would not technically be spurious. But this seems a combination of a questionable reading and an unlikely behavior. Moreover, even in this case, I’d say that the warning could probably be ignored without violating the spirit of the rule, because no one is going to be confused about a side effect not happening that they weren’t expecting anyway.
1
There are no side effects here.
The only time the operand of the sizeof
operator is evaluated is if the type is a variable length array. The compound literal you’ve given is a fixed size array, so it won’t be evaluated at run time.
This is documented in section 6.5.3.4p2 of the C standard regarding the sizeof
operator:
If the type of the operand is a variable length array type, the
operand is evaluated; otherwise, the operand is not evaluated and the
result is an integer constant
1
1. Does
sizeof((int[]){1,2,3})
get evaluated at compile time? And is guaranteed by the standard.
The sizeof
operator is specified as (C11 6.5.3.4):
If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.
And compound literals are explicitly not variable length arrays (VLA):
6.5.2.5 Compound literals
Constraints
The type name shall specify a complete object type or an array of unknown size, but not a variable length array type.
So yes, sizeof((int[]){1,2,3})
is guaranteed to be evaluated at compile-time, although the operand of sizeof
is not evaluated for side effects.
Something like this wouldn’t work: sizeof((int[]){i++})
, the i++
would not get executed and the compiler only needs to know the type of i
to know the size.
2. Does the
sizeof
operand in this case produce side effects?
No. Both the compiler and the MISRA C rule refers to the C language formal definition of a side effect here and not the general English language meaning. The formal definition of the term can be found in C11 5.1.2.3/2:
Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects
Your code doesn’t do any of this so there are no side effects. Meaning that the Tasking warning is quite blunt, it ought to already know that there are no side effects in your code if it claims to be a C compiler.
- Yes
- No
There are two side-effects which sizeof
, kind of, has.
The one which is obvious – padding. Your array of int
does not have that issue, since size of int
is by default match the size of addressed memory. So array of three int
s is exactly equal to size of int multiplied by three.
The less known side effect is if you try to do sizeof(variable length array)
. Then the sizeof
will (sometimes) defer to run-time:
#include <stdio.h>
int main() {
int foo = 100;
double (*bar)[foo];
printf("%ldn", sizeof(*bar));
return 0;
}
5