2014-05-22 57 views
2

我試圖演示異常處理並遇到了一個我無法解決的奇怪問題。問題就出現在下面的代碼:在C++中捕獲自定義sqrt函數的異常失敗

#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; 
} 
+0

我不明白爲什麼它是重複的。即使它是'std',我也不明白爲什麼拋出異常並且沒有捕獲 – RiaD

+0

假設名稱不是問題,如果你沒有拋出異常,函數是無限遞歸的嗎?你的代碼在Visual Studio上生成一個鏈接器錯誤,但是如果函數名稱被改變,那麼在那裏和[這裏](http://ideone.com/uziiN9)工作正常。 –

+0

嗯,從技術上講,鏈接是正確的:這顯然會導致未定義的行爲,因此編譯器可以自由地按照自己的喜好進行操作(例如無法正確捕獲異常)。 – user3667059

回答

2

你只是不能調用函數sqrt,因爲這是保留。你的函數被調用,但你的實現還包括一個頭文件,說sqrt不能拋出。將該函數的名稱更改爲其他名稱,問題將消失。

如果將功能更改爲double sqrt(double const& x) {,也可以看到問題。您可能會收到有關衝突重載的錯誤。