我遇到了一些这样的 C 代码问题:
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]);
不推荐使用的选项很麻烦
Michael Burr提供了一些非常有价值的额外信息,让我能够解决问题。
可编译示例(与实际问题同构):
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
上面的代码编译OK。
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
必须enum
具有union
标记(名称)。
这并不完全准确。示例片段中没有形式参数,并且这些enum
值从未传递给函数。但是如果没有 上的标签enum
,错误仍然会与/Zg
标志一起出现。
(不;我并不是特别喜欢 MSVC 2005。我工作的小组还没有升级到任何更新的版本。大多数情况下它不会影响我。在某些情况下,像这样,当它很痛时。有一天,我会弄清楚为什么 Windows 上的其他构建似乎接受enum
. )
这是严格的 C 代码。MSVC 标记是 Visual-C++ 标记的同义词。