C/C++中的max/min函数宏定义问题

今天遇上了一个不大不小的问题,但是却为此折腾了一天,也算是积累了经验和教训。平时编代码的时候总是绕开问题,只要最后能实现功能就算完成了,实际上每一个bug都是进一步理解C/C++的好机会,现在的问题比较简单,就更应该好好去琢磨,以免日后出现大问题的时候不知道从何处下手。好了,废话不多说了,直接进入正题吧。

刚好最近这段时间我自己的事情大部分都解决了,所以能抽空看看之前项目组的同学发给我的代码。我的习惯就是拿过代码来先编译一下,跑跑看看目前是啥现象,以便调试的时候发现问题的所在。然而这一次连编译都没通过,我觉得很奇怪,她不可能把没通过编译的代码交给我吧。通过对error进行定位,我发现在“modulation.cpp”中有这样的一句话

beta = max(betamin, min(ISR*(y0 - y1) + y0, 1));

显示的是max和min函数未定义。

我给她发QQ,她说在她的平台是可以编译通过的。她的平台是VS2012,而我的平台是VS2010。真的是平台的问题么?我谷歌了一下,发现大家普遍说的解决方案都是加上下面的头文件

#include<algorithm>
using namespace std;

我随手试了一下,发现不行,还是下面有红线。找了半天,终于找到了包含max和min宏定义的头文件“stdlib.h”。我打开了这个文件,相关段落如下

/* Minimum and maximum macros */

#define __max(a,b)  (((a) > (b)) ? (a) : (b))
#define __min(a,b)  (((a) < (b)) ? (a) : (b))
/* Non-ANSI names for compatibility */

#ifndef __cplusplus
#define max(a,b)    (((a) > (b)) ? (a) : (b))
#define min(a,b)    (((a) < (b)) ? (a) : (b))
#endif

里面竟然有max和min的宏定义!但是为什么用不了呢?我尝试着修改一下

/* Non-ANSI names for compatibility */

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

红线消失了!然后我又问她要了她的“stdlib.h”。两个文件大小并不一样,我的是46kb,她的是53kb,证明确实从VS2010进化到VS2012是增加了一下定义或函数的,目前没有时间细看,我直接定位到了相关函数的位置。第一个地方代码是一样的,第二个地方改成了

/* Non-ANSI names for compatibility */

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

竟然也注释了!为了确认是不是源文件本身就注释掉了,我继续在谷歌上搜索这个文件,然而网上好像并没有相关的说明,也没有看到哪有下载VS2012下的“stdlib.h”文件。好在我们班有同学的电脑用的是VS2012,于是问他要了一份,发现源文件并没有注释这两句话,说明这个注释是她自己加的。到这里我有点小不爽,改头文件的事情也不提前说好,感觉并不是诚心让我帮忙调代码。不过这都是小问题,也很庆幸她没有告诉我,我才会有这篇博客。

至此,我找到了问题的关键,于是把代码改成了

beta = __max(betamin, __min(ISR*(y0 - y1) + y0, 1));

编译成功!

下面的连接中的17楼给出了我觉得比较满意的解释
http://bbs.csdn.net/topics/30080771
拷贝如下:首先,max在标准C++中的却是个函数而非宏,其在不同编译系统中的实际定义如下:
linux 下的 g++,头文件

template <class _Tp>
inline const _Tp& max(const _Tp& __a, const _Tp& __b) {
  return  __a < __b ? __b : __a;
}

windows 下的 VC6,头文件 (最新的VS.net没试过,不敢妄言)

template<class _Ty> inline
const _Ty& _cpp_max(const _Ty& _X, const _Ty& _Y)
{return (_X < _Y ? _Y : _X); }

看到了吗? g++按照标准C++的规定把它定义为max();而VC6自作主张把它变成了_cpp_max().
事实上,我提问时所附的源代码是符合标准C++规则的,在g++下顺利编译,而由于VC6把max()变成_cpp_max(),导致无法编译.
要在VC6用max(),只能退而求其次使用_cpp_max().或_MAX().
因为在头文件algorithm包含的另一个头文件xutility里有一句 #define _MAX _cpp_max
另外有一个相关的宏__max, 是定义在stdlib.h中的:#define __max(a,b) (((a) > (b)) ? (a) : (b)),不过__max不是标准C++,是以前的C留下来的.

对了,关于为什么用C++范例的algorithm库不行呢,仔细看了下小红线的解释,没有找到对应的模板,说明是有这个函数的,只是数据类型不匹配,改成下面的形式就可以了!

beta = max(betamin, min(ISR*(y0 - y1) + y0, 1.0));

总结一下吧,这一次的问题虽然不大,但是我收获了很多。最大的感想就是不要轻易的改自带的库函数,如果改了一定要跟合作的人说,不然真的害了别人也害了自己,另外,写代码一定要规范!不然会出现很多奇奇怪怪的问题,就比如最后的那个1改成1.0,作为一个合格的码农,最基本的数据类型转换一定要注意到!

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页