2013-05-05 100 views
4

下面是一個簡單的程序,它說明了這個問題。strerror_r沒有效果

#include <string.h> 
#include <iostream> 

int main() { 
    char buf [30]; 
    strerror_r (0, buf, sizeof (buf)); 

    std :: cout << "strerror_r(0): " << buf << std :: endl; 
    std :: cout << "strerror(0): " << strerror (0) << std :: endl; 
} 

這是輸出。

strerror_r(0): 
strerror(0): Success 

爲什麼buf中沒有什麼?

(編譯在Ubuntu用gcc。)

回答

5

man strerror_r

strerror_r的兼容XSI版本()被提供,如果: (_POSIX_C_SOURCE> = 200112L || _XOPEN_SOURCE> = 600 )& &! _GNU_SOURCE 否則,提供GNU特定版本。

和進一步向下:

具體GNU-strerror_r()指針返回到包含錯誤消息的字符串。這可能是指向函數存儲在buf中的字符串的指針,也可能是指向某個(不可變)靜態字符串(在這種情況下,buf未使用)的指針。如果函數在buf中存儲了一個字符串,那麼至多會存儲buflen字節(如果buflen太小而errnum未知,可能會截斷該字符串)。該字符串始終包含一個終止空字節。

該程序必須使用GNU特定版本,而不是填充buf。我複製了發佈的程序的行爲,但保存了返回值strerror_r(),與buf的地址不同。

+0

我只能確認這一點。 ''strerror_r'在ubuntu中定義爲'char * strerror_r(int,char *,size_t)',使用gcc 4.6.3。 'std :: cout << strerror_r(0,buf,sizeof(buf));'輸出「成功」。 – harpun 2013-05-05 12:38:47

+3

那真是愚蠢。爲什麼地獄不GNU版本有不同的名稱,如果它有不同的語義?荒謬。但是,謝謝。 – spraff 2013-05-05 12:40:16

+1

@spraff:我猜GNU'strerror_r'早於Posix之一。 – 2013-05-05 14:07:54

0
Here is the right way to use strerror_r in cout, ON GNU 

---------------- 
strerror_r(3) - Linux man page 

Name 

strerror, strerror_r - return string describing error number 

Synopsis 

#include <string.h> 

char *strerror(int errnum); 

int strerror_r(int errnum, char *buf, size_t buflen); 
      /* XSI-compliant */ 

char *strerror_r(int errnum, char *buf, size_t buflen); 
      /* GNU-specific */ 
Feature Test Macro Requirements for glibc (see feature_test_macros(7)): 
The XSI-compliant version of strerror_r() is provided if: 
(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE 
Otherwise, the GNU-specific version is provided. 
----------------------------------- 

ON POXIS compiler(RHEL-6) 

------------------ 
Example Program: 
------------------ 
cat testStrerr_r.cpp 

    #include <string.h> 
    #include <iostream> 

     int main() { 
      char buf [30]; 
      //strerror_r (0, buf, sizeof (buf)); 

      std :: cout << "Ravi::"<<strerror_r (0, buf, sizeof (buf))<<std :: endl; 
      std :: cout << "Ravi::"<<strerror_r (1, buf, sizeof (buf))<<std :: endl; 
      std :: cout << "Ravi::"<<strerror_r (2, buf, sizeof (buf))<<std :: endl; 
      std :: cout << "Ravi::"<<strerror_r (11, buf, sizeof (buf))<<std :: endl; 
      std :: cout << "Ravi::"<<strerror_r (12, buf, sizeof (buf))<<std :: endl; 
      std :: cout << "Ravi::"<<strerror_r (13, buf, sizeof (buf))<<std :: endl; 
      std :: cout << "Ravi::"<<strerror_r (14, buf, sizeof (buf))<<std :: endl; 
      return 0; 
     } 

./testStrerr_r 
Ravi::Success 
Ravi::Operation not permitted 
Ravi::No such file or directory 
Ravi::Resource temporarily unavailable 
Ravi::Cannot allocate memory 
Ravi::Permission denied 
Ravi::Bad address