2016-08-07 57 views
1

我是新來的編碼(目前正在學習C++ &我知道一點的C)...errno值不更新(C++)

被閱讀功能math.h中和閱讀有關錯誤號.. 。

據現場我提到: -

域誤差(輸入參數是在其中操作在數學上定義的範圍內,例如標準:: SQRT(-1),標準::日誌外(-1)或std :: acos(2))。如果MATH_ERRNO位被設置,則EDOM被分配給errno。如果MATH_ERREXCEPT位置1,則引發FE_INVALID。

所以我試着用這些知識寫一個小程序...

#include <iostream> 
#include <cerrno> 
#include <cmath> 
using namespace std; 

int main (void) 
{ 
    errno = 0; 
    cout<<"\nWhat I get :-\n"; 
    cout << "log(-3) = " << log(-3) << "\n"; 
    //shouldn't it do (errno = EDOM) in the above step? 
    cout << "errno = " << errno << "\n"; 
    cout << strerror(errno) << "\n"; 

    errno = EDOM; 
    cout<<"\nWhat I want :-\n"; 
    cout << "log(-3) = " << log(-3) << "\n"; 
    cout << "errno = " << errno << "\n"; 
    cout << strerror(errno) << "\n\n"; 

    return(0); 
} 

,並在輸出我看到的errno是沒有得到我的第一個塊更新爲益登即使是-3不是在日誌()的域...

輸出: -

What I get :- 
log(-3) = nan 
errno = 0 
Undefined error: 0 

What I want :- 
log(-3) = nan 
errno = 33 
Numerical argument out of domain 

我不明白我在這裏失蹤... Plz幫助....

我在Mac上編譯Apple LLVM 7.3.0版(clang-703.0.31)上的代碼。

+1

'的std :: ends'無厘頭與普通文本流。除非你需要額外的東西,否則不要使用'std :: endl'。 ''\ n''結束一行。 –

回答

2

#define MATH_ERRNO 1是非法的。您不應該重新定義標準庫符號。 MATH_ERRNO已被標準定義爲1。

您不能設置實現如何處理錯誤(除編譯器特定的開關外,請閱讀編譯器的文檔)。您只能檢查:

if (math_errhandling & MATH_ERRNO) 
    std::cout << "Error reporting uses errno\n"; 
else 
    std::cout << "Error reporting does not use errno\n"; 

if (math_errhandling & MATH_ERREXCEPT) 
    std::cout << "Error reporting uses floating-point exceptions\n"; 
else 
    std::cout << "Error reporting does not use floating-point exceptions\n"; 

對於鐺,相關標誌-fmath-errno/-fmath-no-errno使用/不使用errno

discussion on reported bug看來,標準庫的Mac實現根本不使用errno。所以如果你想使用它來進行錯誤報告,那麼你運氣不好。

+0

好的...我刪除了#define語句...我刪除它後運行代碼,我得到第二個選項「錯誤報告不使用errno」.... – Abhijith

+0

@Abhijith我更新了帖子。它似乎是Mac特定的行爲。 –

+0

@Abhijith _I可以成功地將errno設置爲2 though_。那麼,**你可以將它設置爲任何你喜歡的。它只是一個變量。問題實際上是標準庫沒有設置它。 _這是Mac_上的基礎知識我不是Mac專家,但似乎是的,與Mac捆綁在一起的標準庫不使用'errno'。潛在的解決方案是找到使用它的庫,編譯它並靜態鏈接到你的程序,但是現在,對你來說,它會比它的價值更麻煩。 –

0

你可以找到數學犯錯的完整例子(C)的處理:http://www.cplusplus.com/reference/cmath/math_errhandling/ 對於completness例如從該網站:

#include <stdio.h>  /* printf */ 
#include <math.h>  /* math_errhandling */ 
#include <errno.h>  /* errno, EDOM */ 
#include <fenv.h>  /* feclearexcept, fetestexcept, FE_ALL_EXCEPT, FE_INVALID */ 
#pragma STDC FENV_ACCESS on 

int main() { 
    errno = 0; 
    if (math_errhandling & MATH_ERREXCEPT) feclearexcept(FE_ALL_EXCEPT); 

    printf ("Error handling: %d",math_errhandling); 

    sqrt (-1); 
    if (math_errhandling & MATH_ERRNO) { 
    if (errno==EDOM) printf("errno set to EDOM\n"); 
    } 
    if (math_errhandling &MATH_ERREXCEPT) { 
    if (fetestexcept(FE_INVALID)) printf("FE_INVALID raised\n"); 
    } 

    return 0; 
} 
+0

我收到一條警告,「編譯指示STDC FENV_ACCESS ON不支持 ,忽略編譯指示[-Wunknown-pragmas]」...所以我不確定輸出是否應該是...我得到您發佈的代碼的輸出爲:「錯誤處理:2」 – Abhijith

+0

@Ahhijith _Error處理:2_表示MATH_ERREXCEPT已設置且MA​​TH_ERRNO未設置。 –

+0

這意味着函數使用的錯誤處理機制是MATH_ERREXCEPT,請參閱提供的鏈接中的表格。附:我現在沒有clang編譯器,所以我現在不能檢查未知的編譯指示警告 –