2014-01-15 1 views
11

Является ли это ошибкой в ​​Clang? Следующий код:Clang не может вызывать ошибку при инициализаторах непостоянного массива в режиме C89

#include <stdio.h> 

int main(void) 
{ 
    int foo = 42; 
    int bar[1] = { foo }; 
    printf("%d\n", bar[0]); 
    return 0; 
} 

отлично компилируется с помощью:

clang -Wall -Wextra -Werror -pedantic -pedantic-errors -std=c89 -o foo foo.c 

Я не думаю, что он должен составить, так как список инициализатора bar[] содержит выражение, foo, что не во время компиляции постоянная. В самом деле, если я использую gcc вместо clang я получить ожидаемые результаты:

$ gcc -Wall -Wextra -Werror -pedantic -pedantic-errors -std=c89 -o foo foo.c 
foo.c: In function ‘main’: 
foo.c:6: error: initializer element is not computable at load time 

This question and its accepted answer, наряду с экстрактами this C89 description предполагают, что GCC является правильным и Clang является неправильным:

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

Моя версия лязгом является:

$ clang -v 
Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn) 
Target: x86_64-apple-darwin11.4.2 

Одна вещь, которую я заметил, что последняя версия звоном, который присутствует на opensource.apple.com, я. е. clang 425.0.24, является только 4-ю субминионными версиями старше моего clang, и у него есть модульные тесты для инициализаторов массива. Однако, если я не пропущу что-то, не существует теста для инициализации автоматических массивов с объемной областью с неконстантными выражениями (тестируются только массивы с объемной областью и глобальные массивы). Here's the test file I found.

Итак, в чем заключена сделка?

+0

clang on coliru говорит 'предупреждение: инициализатор для агрегата не является константой времени компиляции [-Wc99-extensions]' –

+0

@ShafikYaghmour Приятно и правильно. Тогда это просто моя обреченная установка/версия компилятора, у которой есть эта проблема? –

+0

Почему downvote? –

ответ

4

Это похоже на ошибку в старой версии clang начиная с версии 3.5 дает мне следующее предупреждение для этого кода:

warning: initializer for aggregate is not a compile-time constant [-Wc99-extensions] 
int bar[1] = { foo }; 
      ^~~~~~~ 

и ошибка с вашими опциями компиляции (see it live).

Не имея публичный проект C89, я нашел gcc есть раздел Non-Constant Initializers, который говорит:

Как и в стандартном C++ и ISO C99, элементы совокупного инициализаторе для автоматической переменной не требуется быть константные выражения в GNU C.

, который подтверждает, что они раньше должны быть константные выражения предварительно C99.

Как вкладка сообщает нам, соответствующая цитата из стандарта C89 от sectioon 3.5.7 и говорит:

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

+3

Вот соответствующий бит (ограничения §3.5.7): «Все выражения в инициализаторе для объекта со статическим хранением или в списке инициализаций для объекта, который имеет совокупность или тип объединения, должны быть постоянными выражениями ». – tab

+0

@tab спасибо за цитату, я добавил ее. –