Windows.h引入"陷阱"

  当你引入#include <Windows.h>头文件后,再使用一些标准库中的函数时,是否会出现编译错误的问题?接下来就简单窥探下具体原因。

一、“陷阱”在哪?

  看如下的几行简单代码:

1 #include <Windows.h>
2 
3 int main()
4 {
5     std::max(1, 10); // 编译错误
6 
7     return 0;
8 }

  

   提示::非法,我们去掉Windows.h头文件后就编译通过了:

        

   如果感觉奇怪,可以将鼠标放到提示错误的函数上面,就看到问题的原因:

       

   好端端地一个标准库函数被宏定义替换,这就是引入Windows.h头文件的“陷阱”之一。

二、导致“陷阱”的根源

  C++编译器编译源文件需要经历几个步骤:预处理 -> 编译 ->链接。其中预处理之一就是宏替换,我们通过IDE快捷方式跳转到max定义的地方:

       

  在预处理Windows.h头文件的时候将std::max(1, 10)简单替换成:std::(((1) > (10)) ? (1) : (10)),编译器在编译的时候就报了上述的错误。不通过IDE,我们也可以通过预处理文件查看替换后的信息:

       

   是不是验证了上面的说法?下面是visual studio IDE生成预处理文件的配置截图:

        

 三、必须要引入Windows.h头文件怎么办?

  如果我们的项目中必须要引入Windows.h头文件,但是我们喜欢用标准库中的函数(std::max, std::min)时该如何避免这个“陷阱”呢?其实很简单,直接使用预处理指令取消掉Windows.h中定义的max和min宏,预处理指令如下:

 1 #include <Windows.h>
 2 #include <algorithm>
 3 #undef max                      // 这行预处理指令
 4 
 5 int main()
 6 {
 7     std::max(1, 10);
 8 
 9     return 0;
10 }

  

  编译通过。当然,引入Windows.h头文件的"陷阱"不只有这个,还有其他的问题,比如头文件包含位置问题导致编译的问题,其实很大程度在预处理的时候出现的问题,需要大家在平时的时候多积累和注意。最好是不涉及Windows API的就不要包含这个头文件了。

原文地址:https://www.cnblogs.com/smartNeo/p/14783031.html