iostream为什么定义abs函数,以及如何停止它
Why does iostream define an abs function, and how can I stop it?
以下c++代码不编译:
int main() {
double a = abs(5.1);
return 0;
}
当然,它抱怨abs
没有定义。但以下内容确实编译了:
#include <iostream>
int main() {
std::cout << abs(5.1) << std::endl;
std::cout << abs(-5.1) << std::endl;
return 0;
}
它输出两个5(而不是5.1)。这很糟糕,原因有很多。首先,abs
是一个非常自然和常见的函数,所以我一直在使用它,但int
部分几乎从来都不是我想要返回的。其次,对我(或使用我代码的人)来说,只写abs
而不注意到它编译了但做了错误的事情太容易了,因为我(他们)真的很善于忽视警告。第三,我只是不明白为什么iostream无论如何都要麻烦定义abs
函数。第四,我真的不明白为什么它会进入全局命名空间。
有什么方法可以防止这个令人反感的abs
函数进入我的全局命名空间吗?
如果重要的话,我正在使用
gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.6)
很可能iostream
包含stdlib.h
来完成它的一些工作。这是头的C版本,它仅在全局命名空间中为int
声明abs
(在C中,必须为double
值使用fabs
)。
我不知道有什么具体的方法可以防止abs
以这种方式被包含,但我知道g++4.5在不让iostream
和string
等基本包含带来多余的东西方面要好得多。
也可能会得到一个警告,即double被截断为int(EDIT:yes,使用-Wconversion
进行警告)。
在C中,包含一个标准标头是不允许表现得像包含任何其他标准标头一样。这避免了您所看到的问题,在实现困难方面付出了相当大的代价。
C++允许任何标准标头包括任何其他标准标头。这使得实现变得相当容易,但可能会导致您所看到的那种问题,包括一个看似不相关的标头会使您不想使用的函数可见,而不是因为您使用的函数根本没有声明而导致错误。
不幸的是,我认为没有一个简单的方法来处理这个问题。尽管很容易想象<iostream>
独立于<stdlib.h>
,但更容易看出它可能需要/想要ios_base
之类的定义。要定义禁止前者同时允许后者的内容,需要相当多的额外工作。
然而,我应该指出,随着时间的推移,这种情况似乎确实有所改善。十年前,几乎所有的标准头球都包括其中的任何一个,这是很常见的。尽管大多数仍然包括至少一些不是严格要求的,但它们通常更接近于每个定义它所需要的。
如果这是一个正在进行的维护问题,为什么不在程序的开头添加一点代码,专门检查abs()
问题?
// test if abs() is defined incorrectly, as would happen if <stdlib.h> were
// included by <iostream>. abs() it should return a float/double, not an int
// (put suggestions here how to fix problem)
if (abs(-5.1) == 5)
{
std::cerr << "Invalid build: abs() defined improperly, ..." << std::endl;
return 2; // exit program by returning from main
}
这将使警告更难被忽视。
- 为什么此代码的矢量迭代器没有停止?
- 为什么循环不会停止?C++
- 为什么我的代码在指针方面停止运行?
- 为什么通过定义另一个指针单元格,整个代码停止工作?
- 为什么Main函数上的Sleep()会停止所有线程
- 不知道为什么它不会停止循环
- 如果我对"while"块发表评论,为什么程序会死机?其中的"yield"线有何影响?
- 为什么我的程序持续运行而不停止?
- C++ char 数组特征:为什么字符串在数组结束之前停止?
- 为什么编译器不会停止在此模板代码上给出错误
- 为什么它停止并以退出代码 11 结束?
- 为什么我可以在不链接任何额外库的情况下包含 sys/*.h
- 为什么 ifstream 的读数超出了 EOF?(即使没有打开文件)如何在EOF停止阅读
- 为什么名称查找在找到使用 using 指令隐式声明的实体时不停止?
- 为什么我的程序在输入main()之前停止工作
- 为什么文件上传在发送几个数据块(使用多部分/表单数据)后停止?
- 非阻塞pthread停止-或者为什么std::atomic_flag会减慢我的代码
- 为什么这是为了使程序停止工作?(C )
- 为什么将高数字传递给递归功能会使我的控制台停止响应
- 为什么Omnet 4.6模拟在运行时停止