Я столкнулся с проблемой с некоторым кодом на С, например:
struct SomeType { ...details immaterial... };
static struct SomeType array[] =
{
{ ... },
...
{ ... },
};
enum { ARRAY_SIZE = sizeof(array) / sizeof(array[0]) };
Компиляторы Unix (различные версии GCC и компиляторы в AIX и HP-UX) были вполне довольны enum
.MSVC 2005 возражал с ошибкой C2056: Illegal Expression
.Согласно MSDN это происходит потому, что «выражение было недопустимым из-за предыдущей ошибки».Это была единственная ошибка, о которой сообщалось, что немного удивляет.
Однако мои вопросы таковы:
- Правильно ли MSVC 2005 интерпретирует стандарт C89 при запрете
enum
? - Являются ли компиляторы Unix слишком щедрыми в разрешении этого без предупреждения?
- Имеет ли C99 (или C2011) какое-либо различие?
- Все еще более поздние версии MSVC все еще возражают против
enum
?
FWIW: приемлемым решением было изменить enum
на:
static int const ARRAY_SIZE = sizeof(array) / sizeof(array[0]);
Устаревшие варианты являются проблематичными
Майкл Берр дал некоторую дополнительную информацию, которая очень ценна, и позволила мне разблокировать проблему.
Скомпилируемый пример (изоморфный фактическим проблемам):
static const char *names[] = { "abc", "def", "ghi" };
enum { NAMES_SIZE = sizeof(names) / sizeof(names[0]) };
static const struct stuff { const char *name; int flags; } array[] =
{
{ "abc", 1 },
{ "def", 2 },
{ "ghi", 3 },
};
enum { ARRAY_SIZE = sizeof(array) / sizeof(array[0]) };
Точная версия MSVC (как указано cl
):
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86
Это версия, которую, по словам Майкла, работает.
И я нашел причину своей проблемы.(Команды ниже приводят к удалению всей специфической для проекта болтовни - множества параметров / D и / I, которые не нужны для примера кода.) Компиляция с помощью:
cl /W3 /c /LD /MD /Od aaa.c
И код выше компилируетсяОК.
cl /Zg /W3 /c /LD /MD /Od aaa.c
Сначала выдается предупреждение:
cl : Command line warning D9035 : option 'Zg' has been deprecated and will be removed in a future release
Я скулил о том, что компиляции выполняются с устаревшими опциями в течение года или более, но никто изКоманда, ответственная за этот подпроект, была готова встать и исправить это, и я не должен - кое-что, что должно измениться.
и затем он говорит:
aaa.c(2) : error C2056: illegal expression
aaa.c(10) : error C2056: illegal expression
Таким образом, опция /Zg
не только устарела, но и является причиной проблемы в первую очередь.Теперь у меня есть лучшие боеприпасы для людей с!
Спасибо за дополнительную информацию, Майкл.
PS: На странице MSDN о /Zg
написано:
Если вы используете опцию /Zg
, и ваша программа содержит формальные параметры типа struct
, enum
или union
(или указатели на такие типы), объявление каждого struct
, *Тип 1074 * или union
должен иметь тег (имя).
Это не совсем точно.В фрагменте примера нет формальных параметров, и значения enum
никогда не передавались в функцию.Но без тега на enum
ошибка все еще появляется с флагом /Zg
.
(Нет; я не особо привязан к MSVC 2005. Группа, в которой я работаю, просто не имеетпока не обновлен до чего-то более позднего. В основном это не влияет на меня. Бывают случаи, например, когда это очень больно. Однажды я пойму, почему другие сборки на Windows, похоже, принимают enum
; боюсь, я обнаружу, что этот конкретный субпродукт не соответствует всем остальным и использует более старый компилятор, чем другие продукты.)
Это строго код на языке Си.Тег MSVC является синонимом тега Visual-C ++.