Search code examples
language-lawyerc11compile-time-constant

Is a string literal converted to bool valid as part of a constant initializer expression?


enum {
  compile_time_assertion = 1 / ("description" && 1);
};

Does the above snippet conform to C11? Having a string literal as part of the expression may violate one of the many constraints for an initializer expression.

  • 6.6p7 lists an address constant as a possible initializer expression.
  • 6.6p9 lists "a pointer to an lvalue designating an object of static storage duration" as a possible address constant.
  • 6.6p9 requires that the expression be created [...] by the use of an expression of array [...] type.

According to the above criteria, a string literal may be used in an initializer expression. Using the string literal in the expression "" && 1 may violate the constraints though:

  • 6.6p6 does not list a string literal as an integer constant expression.
  • 6.6p8 does not list a "pointer to an lvalue" as a possible operand.

Due to this, I concluded that a string literal by itself can be used as an expression in an initializer, but it cannot be used as the operand of the operator &&.

A simple way to transform the above code snippet into an integer constant expression would be to place a sizeof before the string literal.

Is the above reasoning correct? Did I miss anything?


Solution

  • Enumeration constants need "integer constant expressions" (ICE):

    The expression that defines the value of an enumeration constant shall be an integer constant expression that has a value representable as an int.

    The address of a string literal (to which it converts in this context) is not such an ICE.

    So in you reasoning you miss the fact that a string literal converts to its address whenever it is used in an expression. You also seem to miss the definition of ICE which is quite restrictive, in particular more restrictive than what would be a "constant expression of integer type".