【问题标题】:Why does VS not define the alternative tokens for logical operators?为什么 VS 不为逻辑运算符定义替代标记?
【发布时间】:2014-06-25 16:33:46
【问题描述】:

替代标记是 valid c++ keywords,但在 Visual Studio 2013 中会发出编译错误(未声明的标识符):

int main(int argc, const char* argv[])
{
    int k(1), l(2);
    if (k and l) cout << "both non zero\n";

    return 0;
}

and or not 已经存在很长时间了,是否有理由不实施它们

【问题讨论】:

  • 错误信息是什么究竟
  • 我想知道为什么会这样。这不可能是实现的复杂性,如果他们害怕破坏旧代码,同样应该适用于 gcc 等。一个简单的 grep/replace 就可以解决他们的任何代码库冲突,那么是否有更深层次的原因,是幕后有争议还是只是一个没人关心的功能?
  • @NikosAthanasiou 一个简单的 grep/replace 可能会搞砸很多 cmets。
  • GCC 通常比 MSVC 在以符合标准的名义破坏旧代码方面更多更随意。

标签: c++ visual-c++


【解决方案1】:

您询问原因。这是一个可能的原因,不一定是对 Visual C++ 团队影响最大的原因:

  1. 这些是 C 中的有效标识符。
  2. 长期以来,Microsoft 的建议是对 C 和 C++ 代码都使用 C++ 模式,而不是维护现代 C 编译器。
  3. 使用这些作为标识符的有效 C 代码如果被编译为关键字,将会无缘无故地中断。
  4. 尝试编写可移植 C++ 的人大多使用 /permissive-/Za 以获得最大的一致性,这将导致这些被视为关键字。
  5. 通过包含头文件将它们视为/Ze 中的关键字的解决方法既简单又可移植。 (G++ 的解决方法-fno-operator-names 也不错,但是将选项放在源代码中而不是构建系统中会更好一些。)

【讨论】:

【解决方案2】:

VS 不合格。这是旧闻。

要使用替代标记,请包含 &lt;ciso646&gt; 标头。根据标准,包含此标头应该在 C++ 中无效。但是,您在 VS 中确实需要它。因此,只要有可能使用 VS 进行编译,始终包含它是安全的。

【讨论】:

  • 正如已经指出的,这种“不符合”仅特定于默认编译设置。大多数(如果不是全部)编译器在默认模式下不符合标准。指定 /Za 选项会从 VS 编译器中删除这种不符合项。
  • gcc 与 C++11 或更高版本没有 -pthreads 选项是另一个很好的例子。
【解决方案3】:

形式上,这些关键字 被编译器实现并在本质上得到支持,而不包括任何头文件。但是,为此,您必须在 C++ 编译器的“更标准”模式下编译源代码,这意味着使用 /Za 选项。

根据意图,/Za 选项应该“禁用编译器扩展”。当然,不支持兼容编译器中应该存在的东西不能正式限定为“编译器扩展”。然而,这正是目前的情况。

【讨论】:

  • 不回答“为什么?”的问题
  • @Ben Voigt:嗯,它认为“为什么”部分来自“为什么不实施?”。这样的问题是基于一个不正确的前提,因为它们实际上已经实现了。
  • “扩展”是让程序员将这些名称作为标识符。
  • @Ben Voigt:是的,但是“扩展”的正式定义明确表示不允许扩展破坏任何合规代码。换句话说,真正的扩展允许“定义标准未定义的内容”,但不允许“取消定义(或重新定义)标准已经定义的内容”。形式上,允许扩展extend可编译代码的域,但不允许收缩它。
  • 遗憾的是,这对我来说实际上不是一个选项,因为它会导致标准标题中出现很多错误,例如winnt.h(12723): error C2467: illegal declaration of anonymous 'struct'
【解决方案4】:

现代 Visual Studio(或者更确切地说,MSVC)确实支持替代令牌;但是,它只在standards conformance mode 中这样做。这种模式有很多好处,所以应该一直使用它。

要启用它,请将/permissive- 传递给编译器。


以下答案已过时。现在支持,见上文!

以前,Microsoft’s position was1 那个

#include&lt;iso646.h&gt;(或ciso646)是我们支持这些关键字的方式

因为“没有人”(在我之前,2007 年)曾经要求过这个。

1 链接目前已失效;留在这里存档。

【讨论】:

    【解决方案5】:

    (当代更新)

    我做了一个小测试:一个新的“Windows 桌面应用程序”项目。 IDE (Visual Studio 2017 15.7.5) 默认设置以下 C++ 语言一致性设置:/permissive- /Zc:wchar_t /Zc:forScope /Zc:inline。此外,我将 C++ 语言标准 设置为 ISO C++ /最新草案(目前最高为 C++ 17).此外,我在 main() 中添加了以下 2 行:

    bool a, b, c;
    
    a = b and c;
    

    它成功地编译了逻辑运算符的文本形式。但是当我将 IDE Conformance mode 更改为 No (=> without /permissive -) 并重新编译,编译器标记:“error C2065: 'and': undeclared identifier”。

    默认情况下,/permissive- 编译器选项设置在由 Visual Studio 2017 版本 15.5(2017 年 12 月)及更高版本创建的新项目中。在早期版本中默认未设置。因此,如果有人在 15.5 版本之前创建了一个项目,并且在将 IDE 更新到最新版本时,仍然需要在项目中手动设置此编译器选项。

    /Ze 编译器选项(默认启用)启用 Microsoft 扩展。 /Ze 选项已被弃用,因为它的行为默认为开启。 MSDN 建议使用 /Zc(一致性)编译器选项来控制特定的语言扩展功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-14
      • 1970-01-01
      • 2017-11-06
      • 2012-02-15
      • 1970-01-01
      • 1970-01-01
      • 2014-07-01
      相关资源
      最近更新 更多