致命错误C1017:在使用“#if (false)”时无效的整数常量表达式

9

以下代码能够在Linux下工作,但在MSVS下会出错

#if (false)
....
#endif

错误是:致命错误 C1017:无效的整数常量表达式
我在微软网站上找到了这份报告: http://msdn.microsoft.com/en-us/library/h5sh3k99.aspx 虽然与我的情况有点不同,因为我没有使用“#define”。
所以我的问题是:
1. 有没有办法在不改变代码的情况下使其适用于MSVC? 2. 如果必须更新代码,对于这种情况,最好的解决方案是什么?

“因为我没有使用“#define”,那你包含的头文件呢?如果不包含任何头文件,它是否会以相同的方式失败?” - user743382
2
预处理器不知道false或其他关键字的存在 - 这些是给编译器用的。预处理器只知道宏名称和文字常量。将其改为#if 0 - Igor Tandetnik
@IgorTandetnik 对于 C 语言是正确的,但对于这个问题所涉及的 C++ 语言是错误的。 - user743382
@hvd Igor的评论并不是关于C中真实的情况与C++中真实的情况有何不同。它关于Phase 4中真实的情况与非真实的情况。false是C++中的一个关键字,但在Phase 4期间却不是,引用标准来说,“所有标识符都是或不是宏名称 - 没有关键字、枚举常量等”。 - H Walters
@HWalters 这是一条注释。规范文本特别提出两个异常情况:“在执行宏展开和defined一元运算符的所有替换后,所有剩余的标识符和关键字,**除了truefalse**之外,都将被替换为pp-number0,然后每个预处理记号都会转换成一个令牌。”然后就像在#if表达式之外一样,将pp-token转换为令牌。 - user743382
2个回答

4

看起来你的MS编译器版本不支持false作为内置常量。这并不奇怪,因为微软在支持C和C ++标准方面记录不佳。

使其正常工作的一种方法是,在不更改代码的情况下向编译器传递命令行参数,将false定义为0,true定义为1:

-Dfalse=0 -Dtrue=1

只有当MS不支持#if表达式中的false,并且具有特殊的C++规则,即在#if表达式中保留false时,它才会失败。在C中,false不是关键字,#if(false)就很好:false被替换为0。(对于#if(true)或#if(aowehfbwa)也是如此。)因此,我在问题上发表了评论:我比你更有信心,认为MS没有搞砸那么糟糕。 :) - user743382
测试表明,我仅存的那点信任完全是不应该的。你的答案是正确的。但我担心你对“false”和“true”的定义可能会影响重载决议。一些替代方案可以将它们作为“bool”类型的常量保留在“#if”指令之外,这样会更好,但我不确定如何实现。 - user743382
@hvd 这不是 UB 吗?(正如我在我的回答中解释的那样)? - Columbo
@Columbo 假设标准库头文件已被包含,那么是的,行为不符合标准。但是,truefalse定义为宏也未被标准定义:标准没有描述在不符合标准的实现上程序的行为。这是选择较小恶的问题。 - user743382
1
我会将其更改为-Dfalse=(!1)-Dtrue=(!0),以支持typeid和重载解析。此外,现代Visual C++的一些系统头文件会检查关键字是否已定义。这需要禁用。 - Cheers and hth. - Alf

4
有没有不改变代码就能使它在MSVC上工作的方法?
实际上没有。因为有充分的理由,定义一个用于“false”的宏是被标准禁止的,参见[macro.names]/2:
翻译单位不得使用#定义或#取消定义与关键字,在Table 3中列出的标识符相同的名称或描述在7.6中的属性令牌。
我也看不到其他办法。
如果代码必须更新,这种情况下最好的解决方案是什么?
将“false”替换为“0”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接