2016-04-16 2 views
0

Я был кодированием мини-GTK + 2.0, когда у меня была проблема. Когда я пишу это:Инициализация массива с константной переменной

const unsigned LABEL_NUMBER = 4; 
const char *LABEL_TEXT[4] = { 
           "Five or More", 
           "By ... " 
           "& ...", 
           "April 2016", 
           "~~ Thanks for playing ~~" 
          }; 

Нет проблем. Но когда я пишу это:

const unsigned LABEL_NUMBER = 4; 
const char *LABEL_TEXT[LABEL_NUMBER] = { 
              "Five or More", 
              "By ... " 
              "& ...", 
              "April 2016", 
              "~~ Thanks for playing ~~" 
             }; 

Gcc ответы:

source/gui.c: In function ‘create_about_window’: 
source/gui.c:202:4: error: variable-sized object may not be initialized 
    const char *LABEL_TEXT[LABEL_NUMBER] = { 
    ^
source/gui.c:203:34: error: excess elements in array initializer [-Werror] 
            "Five or More", 
           ^
source/gui.c:203:34: note: (near initialization for ‘LABEL_TEXT’) 
source/gui.c:204:34: error: excess elements in array initializer [-Werror] 
            "By ... & ..." 
           ^
source/gui.c:204:34: note: (near initialization for ‘LABEL_TEXT’) 
source/gui.c:206:34: error: excess elements in array initializer [-Werror] 
            "April 2016", 
           ^
source/gui.c:206:34: note: (near initialization for ‘LABEL_TEXT’) 
source/gui.c:207:34: error: excess elements in array initializer [-Werror] 
            "~~ Thanks for playing ~~" 
           ^
source/gui.c:207:34: note: (near initialization for ‘LABEL_TEXT’) 

Так что я просто хочу знать, почему GCC отображает эти ошибки во время я использую постоянное целое число без знака, чтобы установить размер массива?

+0

[Работает на моей машине] (http://coliru.stacked-crooked.com/a/bb6ad14a4c89e222) –

+0

Требуется поведение для компиляторов C; 'const unsigned LABEL_NUMBER = 4;' - переменная - хотя и не изменяющая значение. Массивы поставляются в двух вариантах; те, размер которых фиксируется постоянной целочисленного значения времени компиляции (который может быть инициализирован), и те, у которых переменный размер (который не может быть инициализирован). Поскольку в терминах C-компилятора (C-стандарт) последний является переменной, у вас есть переменно-модифицированный массив и не может использовать инициализаторы. В случае сомнений используйте 'enum {LABEL_NUMBER = 4};'. Это будет отображаться в вашей таблице символов, но может использоваться в измерениях массива. –

+2

Любопытно использовать конкатенацию строк в двух кратчайших строках в инициализаторах. ('" By ... "" & ... ",' является одной строкой, потому что после второй двойной кавычки нет запятой.) –

ответ

1

Массивы переменной длины не могут быть инициализированы с использованием инициализаторов.

С11 - §6.7.9/3:

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

+0

Я как бы шокирован тем, что он компилируется: http://coliru.stacked-crooked.com/a/bb6ad14a4c89e222 –

+1

@MooingDuck; В C++ квалифицированные объекты 'const' рассматриваются как реальные постоянные литералы (за некоторыми исключениями). Вы компилируете с помощью 'g ++'. Это компилятор C++. – haccks

+0

Но я не понимаю, почему LABEL_TEXT [] является VLA, char * LABEL_TEXT [const ...] == char * (LABEL_TEXT [const ...]) нет? – Maxime

0

Вы можете определить LABEL_NUMBER, как макрос:

#define LABEL_NUMBER 4 

этак LABEL_NUMBER

const char *LABEL_TEXT[LABEL_NUMBER] 

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

const char *LABEL_TEXT[4] 

для компилятора для компиляции.

+0

Спасибо за ваш ответ, но это не совсем то, что я просил :) – Maxime

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