Wolfgang Riedel wrote:
> Simon Biber wrote:
>> Wolfgang Riedel wrote:
>>> so this should be valid (and compiles with -Wall -pedantic -std=c99):
>>>
>>> #include <string.h>
>>>
>>> size_t blah = strlen("abc");
>>>
>>> /*...*/
>> It's not valid, and gcc produces the diagnostic message "initializer
>> element is not constant" when compiled with exactly the options you give.
>>
>> --
>> Simon.
>
> You snipped the rationale, I quoted.
> I think it's correct (evaluates to arithmetic constant exrpssion).
>
No. The relevant definition is
"An arithmetic constant expression shall have arithmetic type and shall only
have operands that are integer constants, floating constants, enumeration
constants, character constants, and sizeof expressions. Cast operators in an
arithmetic constant expression shall only convert arithmetic types to
arithmetic types, except as part of an operand to a sizeof operator whose
result is an integer constant."
'strlen("abc")' doesn't qualify. gcc is free to evaluate 'strlen("abc")' as
a constant expression, but this does not make it an arithmetic constant
expression. Of course, the initializer to "blah" need only be a constant
expression. It doesn't have to be an arithmetic constant expression
specifically.
> Btw. my gcc doesn't warn (maybe not the latest & greatest):
>
<snip>
Not a bug. Later versions of gcc do warn because standards-conforming
compilers are not required to accept the program, but gcc does not violate
the standard by not issuing a diagnostic -- implementations are expressly
allowed to accept other forms of expressions as constant than the ones
described by the standard.
If you expect 'strlen("abc")' to be a constant expression, you're relying on
an extension. It's not portable code.
Note that gcc does *not* allow expressions that cannot be evaluated at
compile time as initializers, and rightly so. This will not compile:
size_t foo();
size_t blah = foo();
S.
|