Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C - initializer not constant with string literal

Tags:

c

I am aware of the limitations for initializers at file-scope in c: you cannot use a variable (even const), functions etc... But I really do not understand why this does not work:

#include <stdlib.h>
#include <stdio.h>

//unsigned long a = "string"[0] > '0'; // this does not compile
unsigned long a = 's' > '0'; // this works fine, output is "a = 1"

int main(void)
{
    printf("a = %lu\n",a);

    return 0;
}

Why does the line with the string literal gives: error: initializer element is not constant. Are string literals not considered constant? Is there any way to make it work?

Thanks in advance

like image 996
G. Communithings Avatar asked Feb 01 '18 12:02

G. Communithings


2 Answers

Your variable has static storage duration, as such and according to N1570 (C11) §6.7.9/p4:

All the expressions in an initializer for an object that has static or thread storage duration shall be constant expressions or string literals.

String literals have static storage duration §6.4.5/p6, so their addresses can be considered constant expressions (which is why they are allowed as initializers). But you are trying to access the value at such an address, and the C standard explicitly forbids it. To quote §6.6/p9, emphasis mine:

An address constant is a null pointer, a pointer to an lvalue designating an object of static storage duration, or a pointer to a function designator; it shall be created explicitly using the unary & operator or an integer constant cast to pointer type, or implicitly by the use of an expression of array or function type. The array-subscript [] and member-access . and -> operators, the address & and indirection * unary operators, and pointer casts may be used in the creation of an address constant, but the value of an object shall not be accessed by use of these operators.

On the other hand, when you used character constants for comparison, you obtain a valid constant expression.

like image 101
StoryTeller - Unslander Monica Avatar answered Nov 09 '22 02:11

StoryTeller - Unslander Monica


In C language objects with static storage duration have to be initialized with constant expressions or with aggregate initializers containing constant expressions.

Now here you had basically "string"[0] as an constant expression? But is it so?

The thing is From 6.6p2

A constant expression can be evaluated during translation rather than runtime, and accordingly may be used in any place that a constant may be.

Now after that I checked the translation phases and what it consists of: It will be clear that none of the expression is evaluated which involves a [] array subscripting over string literal. This literally involves dereferencing an address and getting the vlaue which is not possible to do in translation phases. That's why this error.

like image 40
user2736738 Avatar answered Nov 09 '22 02:11

user2736738