c++ - 滥用函数式宏 max 的流行标头
问题描述
在Programming Principles and Practice Using C++, Second Edition的第 1057 页上,Bjarne Stroustrup 讨论了类函数宏的问题。
他从一个例子开始。下面的宏:
#define MAX(x, y) ((x)>=(y)?(x):(y))
在以下行中使用:
double dd = MAX(aa++, 2);
替代品成为:
double dd = ((aa++)>=(2)?(a++):(2));
关于这个例子,他解释说:
另一方面,并非世界上所有的括号都可以保存第二次扩展。宏参数
x
被赋予了值aa++
,并且由于x
在 中使用了两次MAX
,a
因此可以增加两次。不要将具有副作用的参数传递给宏。碰巧的是,一些天才确实定义了一个这样的宏,并将其粘贴在一个流行的头文件中。不幸的是,他也称它为
max
,而不是MAX
,所以当 C++ 标准头文件定义
template<class T> inline T max(T a, T b) {return a<b?b:a;}
用
max
参数扩展,T a
编译T b
器看到
template<class T> inline T ((T a)>=(T b)?(T a):(T b)) {return a<b?b:a;}
编译器错误消息是“有趣的”并且不是很有帮助。在紧急情况下,您可以“取消定义”宏:
#undef max
.
Bjarne Stroustrup 的故事听起来在 C++ 社区中很有名,但是,我在网上找不到更多关于它的文章。Bjarne Stroustrup 在这里的挫败感表明这个特定的头文件在开发 C++ 时产生了向后兼容性问题。
Bjarne 在他的故事中提到的标题是什么?
解决方案
推荐阅读
- django - 端口转发已配置,netstat 说端口已打开但无法访问服务器(ping 失败)
- c - C、调用fread时消除循环?
- reactjs - 无法使用 React.js create-react-app 自动刷新
- sql - 表头和多个明细表查询问题
- r - Shiny/R - 格式化输入内容
- javascript - 为什么 Promises 在 async/await 中同时解决
- r - R / R Shiny:无法在R中的writeLines之后插入换行符
- json - 无法解决 JSON Put api 的 EOF 解析错误
- php - Slim4 通过 openapi-generator 部署问题
- java - poi xwpf 解析器中是否有 mc:AlternateContent 和 Mc:Fallback 支持?