gpt4 book ai didi

c - 是 Unix 编译器太松懈了,还是 MSVC 2005 缺少一个技巧?

转载 作者:行者123 更新时间:2023-12-05 01:35:07 26 4
gpt4 key购买 nike

我遇到了这样一些 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:非法表达式。根据MSDN ,这是因为“由于先前的错误,表达式无效”。这是报告的唯一错误,这让人有点惊讶。

但是,我的问题是:

  1. MSVC 2005 是否在禁止 enum 方面准确地解释了 C89 标准?
  2. Unix 编译器在没有警告的情况下允许这样做是否过于慷慨?
  3. C99(或 C2011)有什么区别吗?
  4. MSVC 的最新版本是否仍然反对enum

FWIW:可接受的解决方案是将 enum 更改为:

static int const ARRAY_SIZE = sizeof(array) / sizeof(array[0]);

弃用的选项很麻烦

Michael Burr提供了一些非常有值(value)的额外信息,并帮助我解决了问题。

可编译示例(与实际问题同构):

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

这就是 Michael 所说的版本。

而且,我找到了我的问题的原因。 (下面的命令行删除了所有项目特定的废话——示例代码不需要的大量/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:关于 /Zg 的 MSDN 页面说:

If you use the /Zg option and your program contains formal parameters that have struct, enum, or union type (or pointers to such types), the declaration of each struct, enum, or union type must have a tag (name).

这并不完全准确。示例片段中没有正式参数,enum 值从未传递给函数。但是没有enum上的标签,错误仍然出现在/Zg标志上。


(不;我不是特别喜欢 MSVC 2005。我工作的小组还没有升级到任何更新的东西。大多数情况下它不会影响我。有些时候,像这样,当它伤害很多。总有一天,我会搞清楚为什么 Windows 上的其他构建似乎正在接受 enum;我担心我会发现这个特定的子产品与其他所有产品都不一致并使用比其他产品更旧的编译器。)

这是严格的 C 代码。 MSVC 标签是 Visual-C++ 标签的同义词。

最佳答案

这在 C89 中当然是合法的(只要生成的数组大小可表示为 int)。

§3.5.2.2 中对枚举常量定义值的约束是:

The expression that defines the value of an enumeration constant shall be an integral constant expression that has a value representable as an int.

§3.4 描述了整数常量表达式:

Constraints

Constant expressions shall not contain assignment, increment, decrement, function-call, or comma operators, except when they are contained within the operand of a sizeof operator.

Each constant expression shall evaluate to a constant that is in the range of representable values for its type.

Semantics

An expression that evaluates to a constant is required in several contexts. If the expression is evaluated in the translation environment, the arithmetic precision and range shall be at least as great as if the expression were being evaluated in the execution environment.

An integral constant expression shall have integral type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions, and floating constants that are the immediate operands of casts. Cast operators in an integral constant expression shall only convert arithmetic types to integral types, except as part of an operand to the sizeof operator.

关于c - 是 Unix 编译器太松懈了,还是 MSVC 2005 缺少一个技巧?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9883939/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com