您的位置:首页 > 编程语言 > C语言/C++

C++中的宏和函数名称的冲突 STL+windows.h

2009-03-03 12:21 363 查看
最近在写代码的时候总是发现在#include"windows.h"了以后经常用STL中的min.max函数出现编译错误。但是自认为代码是没有错误的。下面就是相关的代码:

// testMacro.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <limits>
#include <algorithm>
#include "windows.h"
int _tmain(int argc, _TCHAR* argv[])
{
int k = std::numeric_limits<int>::max();
int b = std::max(1,3);
return 0;
}


这里的numeric_limits模板类和那个std::max都不约而同的遇上了编译错误:

1>c:/project/testapplication/c++/testmacro/testmacro/testmacro.cpp(12) : error C2589: '(' : illegal token on right side of '::'
1>c:/project/testapplication/c++/testmacro/testmacro/testmacro.cpp(12) : error C2059: syntax error : '::'

搜索了网上看到了这个帖子.确实冲突是存在的。在#include"windows.h"之后,编译器把这里的max()调用都用windef.h里面的宏展开了.

#ifndef NOMINMAX
#ifndef max
#define max(a,b)            (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a,b)            (((a) < (b)) ? (a) : (b))
#endif
#endif  /* NOMINMAX */


说明宏的替换是发生在语法分析之前的。当然解决方案也是有的。最简单的方案就是在工程编译的时候添加一个NOMINMAX的宏,那样这些宏就不会编译在里面,那问题也解决了。还有一个办法就是你在调用函数的时候都加上括号,让函数看上去想函数指针一样:

int k = (std::numeric_limits<int>::max)();
int b = (std::max)(1,3);


虽然这样的话,问题解决了。但是留给我们更多的想法是函数名称定义上需要注意的地方。如果我自己定义一个类,然后里面的函数名是max或者min的话,是不是在调用的时候也有一样的问题呢??回答是肯定的。还是前面的例子。

#include "stdafx.h"
#include <limits>
#include <algorithm>
#include "windows.h"
class Test
{
public:
int max()
{
return 1;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
int k = (std::numeric_limits<int>::max)();
int b = (std::max)(1,3);
return 0;
}


尝试加入一个Test类,里面有一个max函数。这里不需要调用就不能通过编译,因为编译器已经给你做了展开。

1>c:/project/testapplication/c++/testmacro/testmacro/testmacro.cpp(12) : warning C4003: not enough actual parameters for macro 'max'
1>c:/project/testapplication/c++/testmacro/testmacro/testmacro.cpp(12) : error C2059: syntax error : ')'
1>c:/project/testapplication/c++/testmacro/testmacro/testmacro.cpp(12) : error C2334: unexpected token(s) preceding ':'; skipping apparent function body

这个就是相关的错误。给我们的提醒就是函数名称的定义不要和宏定义的名称相同,或者说在C++里面尽量不要用宏!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: