2013-08-10 3 views
8

У меня есть программа с некоторыми глобальными строками, определенных в верхней части файла, как это:C: Назначение «статический Const символ * сопзЬ», чтобы «статический Const символ *»

static const char * const STRING_A = "STRING A"; 
static const char * const STRING_B = "STRING B"; 

Затем в основной программе loop Я неоднократно вызываю функцию. Эта функция содержит указатель, который должен указывать на приведенные выше строки, в зависимости от пользовательского ввода. По умолчанию я хочу, чтобы установить в STRING_A, так что я по существу есть это:

// Called repeatedly from a loop. 
void input_function() 
{ 
    static const char *current = STRING_A; 

    // Do stuff and reassign different strings to "current" 
    ... 
} 

Проблема, что у меня есть, что при компиляции я получаю «ошибка: инициализатор элемент не является постоянным». Это использует GCC 4.7.2. Что меня больше смущает, так это то, что ошибка исчезает, если я избавлюсь от «статического» ключевого слова во входной функции. Однако это не решение, поскольку ключевое слово static необходимо для отслеживания текущей строки между вызовами.

Очевидно, я мог бы исправить это разными способами, просто просто избавившись от некоторых квалификаторов const. Но я хочу понять, почему это не работает.

Мое настоящее понимание заключается в том, что глобальные строковые переменные не могут быть изменены, чтобы указывать на разные строки, а также не изменять их отдельные символы. Ключевое слово static хранит их локально в исходном файле.

Для переменной current в моей функции я понимаю, что статическое ключевое слово позволяет сохранить его значение по нескольким вызовам функции, а в этом случае определитель констант означает, что строка, на которую указывает current, может измениться - но не символы строки, на которую он указывает.

Я не вижу конфликтов в этих утверждениях, поэтому я не понимаю, почему компилятор дает ошибку - особенно, почему у него нет проблем, если удаляется 0 статический спецификатор .

Спасибо, если кто-то может объяснить, в чем проблема.

ответ

7

6.7.8/4 [С99]:

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

STRING_A не является ни, следовательно, ошибка.

Один на пути, чтобы обойти это было бы по следующим направлениям:

void input_function() 
{ 
    static const char *current = NULL; 
    if (current == NULL) { 
     current = STRING_A; 
    } 

    ... 
} 
+0

Я все еще обертывание мою голову вокруг него, но спасибо за быстрый ответ. –

3

Это потому, что STRING_A не является константой времени компиляции. Ваши интерпретации правильны, однако вы не можете инициализировать константу как непостоянное значение (например, STRING_A).

Как компилятор знает, что STRING_A указывает на то, что он компилируется? Это не так: STRING_A будет указывать на разные адреса в разделе только для чтения памяти при каждом выполнении программы, в зависимости от того, где находится строковый литерал.

Вы должны сделать следующее, чтобы работать вокруг этого ограничения, а относящиеся тот же эффект:

// Defines current to be a null pointer. 
static const char *current = NULL; 

// Determine if current is a null pointer. 
if (current == NULL) current = STRING_A; 
+0

Спасибо за быстрый ответ, я должен был дать его NPE, хотя потому, что он был как-то еще быстрее. Еще раз спасибо. –

Смежные вопросы