为啥VC++编译器提示标识符未定义?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥VC++编译器提示标识符未定义?相关的知识,希望对你有一定的参考价值。

'IDC_HAND' : undeclared identifier
'iCmdShow' : undeclared identifier

这两个都是在MSDN里面有的。为什么还出现这种问题?我用的是VC++ 6.0的版本
'iCmdShow' : undeclared identifier的问题貌似解决了,在 WinMain函数中的那个参数就是,但是'IDC_HAND'这个为什么会提示没有定义呢

参考技术A 在需要的地方自己定义一下:
#define IDC_HAND MAKEINTRESOURCE(32649)本回答被提问者和网友采纳
参考技术B #include <windows.h> 参考技术C 你想设置鼠标光标是吧,应该是IDI_HAND。

为啥 VS 不为逻辑运算符定义替代标记?

【中文标题】为啥 VS 不为逻辑运算符定义替代标记?【英文标题】: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 在以符合标准的名义破坏旧代码方面更多更随意。 【参考方案1】:

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

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

【讨论】:

能否修改/Za 部分,好吗?显然它有很多错误,微软不鼓励使用它(当然,grrr 不在文档中)。见reddit.com/r/cpp/comments/76pmky/til_c_has_and_or_and_not/… 另外请注意,/Za 会导致 MSVC 中出现错误,当包含windows.h 时会触发编译器错误。我在查看此帖子后遇到此问题,因此对此进行了报告:github.com/SasLuca/MSVCBug/blob/master/README.md 如果您遇到/Za 的问题,请改用/permissive-【参考方案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(一致性)编译器选项来控制特定的语言扩展功能。

【讨论】:

以上是关于为啥VC++编译器提示标识符未定义?的主要内容,如果未能解决你的问题,请参考以下文章

Mfc中release下提示未定义入口点,在debug模式下可以正常运行,这是为啥啊,应该怎么解

VS提示:未定义标识符“printf”。有头文件,能过编译,就是显示红波浪线,求助大神

VS2015提示gets未定义

#include<iostream> 存在,但出现错误:标识符“cout”未定义。为啥?

webpack jquery已经全局引入 为啥还是提示$未定义

今天刚安装了vs2017,新建好项目后发现无法打开源文件和未定义标识符的错误是怎么回事?