【发布时间】:2014-05-22 23:29:26
【问题描述】:
我试图演示异常处理,但遇到了一个我无法解决的奇怪问题。问题出现在以下代码中:
#include <iostream>
#include <cmath>
#include <stdexcept>
using namespace std;
double sqrt(double x) {
if ( x < 0 ){
throw invalid_argument("sqrt received negative argument");
}
return sqrt(x);
}
int main(int argc, char *argv[]) {
try {
double s = sqrt(-1);
}
catch (const exception& e) {
cout << "Caught " << e.what() << endl;
}
return 0;
}
代码失败:
terminate called after throwing an instance of 'std::invalid_argument'
what(): sqrt received negative argument
./dostuff.sh: line 8: 3472 Aborted (core dumped) ./may_22.exe
但是,如果我将写入的 sqrt 函数的名称更改为“mySqrt”,或者删除标头,则可以正确捕获异常。知道是什么原因造成的吗?
我正在编译通过
g++ -g -Wall -std=c++0x -Weffc++ may_22.cpp -o may_22.exe
g++ (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
编辑:澄清一下,这似乎不是命名空间问题。代码显然在调用我的 sqrt 函数,如异常消息所示。
编辑 2:此代码仍然无法为我处理异常。
#include <iostream>
#include <cmath>
#include <stdexcept>
double sqrt(double x) {
if ( x < 0 ){
throw std::invalid_argument("sqrt received negative argument");
}
return std::sqrt(x);
}
int main(int argc, char *argv[]) {
try {
double s = sqrt(-1);
}
catch (std::exception& e) {
std::cout << "Caught " << e.what() << std::endl;
}
return 0;
}
【问题讨论】:
-
我不明白为什么它是重复的。即使在
std我也不明白为什么会抛出异常而没有被捕获 -
假设名称没有问题,如果你不抛出异常,函数不会无限递归吗?您的代码会在 Visual Studio 上生成链接器错误,但在那里可以正常工作,如果函数名称发生更改,here。
-
好吧,从技术上讲,链接是正确的:这显然会导致未定义的行为,因此编译器可以随意做任何事情(例如无法正确捕获异常)。
-
我认为这个问题应该被解锁,因为这里有信息。 Sqrt 作为 c 库的一部分存在于全局命名空间中。 std::sqrt 是否有可能在您的系统上以 ::sqrt 的形式实现?