microsoft sdks\windows\v6.0a\include\gdiplustypes.h(658) : error C3861: 'min': identifier not found
周末调试mfc程序, 因为程序中要调用OpenCV的库。
但是出现了:microsoft sdks\windows\v6.0a\include\gdiplustypes.h(658) : error C3861: 'min': identifier not found
这么一个问题。 在网上查呢,他们的解释都是关于,他们建的工程不是mfc程序, 是调用了CMake。
如:websit。 但是呢,我这建立的就是mfc程序。 加了NOMAXMIN都没有用。
后面找到问题的根本原因了:原因是因为我包含的第三方库的OpenCV的头文件和系统头文件相冲突。
这就涉及到了C++中头文件的包含顺序问题。 然后我把第三方库的头文件放到最后, 并且是"" 去包括头文件。
[cpp] view plain copy
1. #include
2. #include "opencv2/opencv.hpp"
再去编译就编译成功了。
这里面包含了一个关于C++头文件的包含顺序研究。 具体可以参考。
http://www.uml.org.cn/c++/201203085.asp
在调试程序时出现了下面的问题,说找不到min和max标识符。
1>c:\program files\microsoft sdks\windows\v7.0a\include\gdiplustypes.h(471): error C3861: “min”: 找不到标识符
1>c:\program files\microsoft sdks\windows\v7.0a\include\gdiplustypes.h(472): error C3861: “max”: 找不到标识符
后来在网上查了些资料说是第三方库头文件与系统头文件发生了冲突,又想到之前有大概看过的google编程规范,有专业讲包含文件的名称和次序这一块,果然。问题就出现在这里。先贴出里面讲到的规范:
将包含次序标准化可增强可读性、避免隐藏依赖(hidden dependencies,译者注:隐藏依赖主要是指包含的文件中编译时),次序如下:C库、C++库、其他库的.h、项目内的.h。
项目内头文件应按照项目源代码目录树结构排列,并且避免使用UNIX文件路径.(当前目录)和..(父目录)。例如,google-awesome-project/src/base/logging.h应像这样被包含:
#include"base/logging.h"
dir/foo.cc的主要作用是执行或测试dir2/foo2.h的功能,foo.cc中包含头文件的次序如下:
dir2/foo2.h(优先位置,详情如下)
C系统文件
C++系统文件
其他库头文件
本项目内头文件
这种排序方式可有效减少隐藏依赖,我们希望每一个头文件独立编译。最简单的实现方式是将其作为第一个.h文件包含在对应的.cc中。
dir/foo.cc和dir2/foo2.h通常位于相同目录下(像base/basictypes_unittest.cc和base/basictypes.h),但也可在不同目录下。
相同目录下头文件按字母序是不错的选择。
举例来说,google-awesome-project/src/foo/internal/fooserver.cc的包含次序如下:
#include"foo/public/fooserver.h" // 优先位置
#include
#include
#include
#include
#include"base/basictypes.h"
#include "base/commandlineflags.h"
#include "foo/public/bar.h"
一开始cpp中的头文件顺序是:
后来将系统库的头文件提到前面来
问题就解决了,原因是OpenCV库与系统库冲突了,后来又看了哥们写的比较精典的贴:
http://www.uml.org.cn/c++/201203085.asp C++头文件的包含顺序研究
里面分析的比较详细,里面还讲到编程思想提到的另一种头文件包含方式,也就是反过来,把标准库放在最后面,这样内部出现就会很容易发现,就如一开始的库冲突,但反过来又一想,库冲突的解决方法又是用到第一种包含方式,那还不如一直用google编程规范里面提到的规范就好!!