【问题标题】:Why does including windows.h create syntax errors, preventing instantiation of a class? (C2146, C2065)为什么包含 windows.h 会产生语法错误,从而阻止类的实例化? (C2146, C2065)
【发布时间】:2020-07-10 20:04:20
【问题描述】:

(平台详情:Windows 10、Visual Studio C++ (MSVC 14.26.28801))

这是一个基本的重现。考虑以下运行良好的程序:

struct Rectangle {};

int main() {
    Rectangle rect {};
}

按预期编译和运行。

但是现在如果我们像这样引入 windows.h 的导入:

#include <Windows.h>

struct Rectangle {};

int main() {
    Rectangle rect {};
}

我们得到以下编译错误:

  • syntax error: missing ';' before identifier 'rect' (C2146) [25, 5]
  • 'rect': undeclared identifier (C2065) [25, 5]
  • expected a ';' [25, 15]
  • 'rect': undeclared identifier (C2065) [26, 5]
  • identifier "rect" is undefined [26, 32]
  • function call missing argument list (C4551) [25, 5]

哎呀!

Microsoft 的文档并没有提供太多见解: https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/compiler-error-c2146?view=vs-2019

(我还是 C++ 新手,如果这很明显,请道歉)

我假设 windows.h 中某处有某种...指令会改变某种行为,但我不确定要搜索或查找什么。

谢谢!

【问题讨论】:

    标签: c++ windows winapi visual-c++


    【解决方案1】:

    好的,找到答案了。

    我使用Rectangle 作为“hello world”示例。

    原来 windows.h 已经包含一个“矩形”,表示符号碰撞

    (https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-rectangle)

    隐含的“windows.h 中的所有内容现在都可以在全局命名空间中使用!”让我措手不及。

    (将我的班级名称切换为“Marks_Rectangle”可以解决问题!)

    【讨论】:

    • Rectangle 是一个函数,而不是一个类。 Windows API 中没有任何类(在窗口类之外,但那些不是您的 C++ 类)。
    • FWIW,如果您愿意,也可以选择 MarksNamespace::Rectangle
    • 这不是“命名空间冲突”。发生碰撞的是“符号”。当然,整个 Windows API 都存在于全局命名空间中。毕竟是 C 语言(GDI+ 是个奇怪的东西,但它确实是一个基于平面 GDI+ API 的库)。
    • 感谢大家的指点!超级欣赏!更新了正确答案。
    • 抱歉,不是"symbols",而是"identifiers""symbols" 是链接器看到的,而不是编译器。
    猜你喜欢
    • 2016-10-01
    • 1970-01-01
    • 2022-08-07
    • 2016-11-19
    • 1970-01-01
    • 1970-01-01
    • 2015-03-19
    • 2015-12-22
    • 1970-01-01
    相关资源
    最近更新 更多