2013-05-05 98 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