Почему я не могу инициализировать статическую переменную не буквальным значением? - PullRequest
7 голосов
/ 26 марта 2012

У меня был этот код:

int foo(void){
    return 1;
}

int main(void){
    static const int x = foo();

    //do stuff
    return 0;
}

Но я получил ошибку об инициализации статической переменной неконстантным значением. Я думал, что это как-то связано со спецификатором const, но это не так. Я закончил отбрасывать ключевое слово const и сделал это:

int foo(void){
    return 1;
}

int main(void){
    static int x = 0;
    if (x == 0) x = foo();

    //do stuff
    return 0;
}

Теперь, почему компилятор не может просто отложить инициализацию переменной static int x до тех пор, пока она не будет использована, и, что более важно, почему он не может просто поместить ее в раздел для чтения и записи и просто принудительно установить, что это не так? записано во время компиляции? Я хотел бы использовать ключевое слово const AND static для улучшения семантики в моем коде, но мне все равно, как компилятор справится с этим, просто позвольте ему работать.

Мое понимание стандарта C неверно? Или мой компилятор сосет? Это MSVC 9.0.

Ответы [ 3 ]

8 голосов
/ 26 марта 2012

C требует этого.

Из стандарта C:

(C99, 6.7.8p4) "Все выражения в инициализаторе для объекта со статической продолжительностью хранения должны быть константными выражениями или строковыми литералами."

Обратите внимание, что квалификатор const означает не константу, а только для чтения. const объект не является константой в C.

Причина, по которой статический объект не может быть инициализирован непостоянным значением, связана с тем, что инициализация статического объекта выполняется «до запуска программы» (C99, 6.2.4p3).

1 голос
/ 26 марта 2012

Это ограничение взято из раздела 6.7.8 / 4 стандарта C, так что это не только ваш компилятор:

Все выражения в инициализаторе для объекта со статической продолжительностью хранения должны быть константными выражениями или строковыми литералами.

Причиной этого является то, что в отличие от стандарта C ++, для C-s не требуется, чтобы среды выполнения обеспечивали точку входа для предварительной инициализации (хотя, конечно, не запрещает it; способ и время статической инициализации ( 5.1.2) не указано ).

1 голос
/ 26 марта 2012

Значение для инициализации должно быть определено во время компиляции или соединения. В C нет концепции конструкторов, которые можно запускать при запуске программы.

...