如何获得POSIX strerror_r而不是GNU版本?

我如何获得POSIX strerror_r而不是GNU版本?

我在Ubuntu 8.04上用glibc 2.7(基于内容)编译g ++

编辑

在上面的手册页上说:

glibc的functiontestingmacros要求(请参阅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. 

然后它在feature_test_macros(7)中说 :

  If no feature test macros are explicitly defined, then the following feature test macros are defined by default: _BSD_SOURCE, _SVID_SOURCE, _POSIX_SOURCE, and _POSIX_C_SOURCE=200809L (200112L in glibc versions before 2.10; 199506L in glibc versions before 2.4; 199309L in glibc versions before 2.1). 

所以我应该得到的POSIX版本,但我得到的GNU之一。

string.h文件string.h

 /* Reentrant version of `strerror'. There are 2 flavors of `strerror_r', GNU which returns the string and may or may not use the supplied temporary buffer and POSIX one which fills the string into the buffer. To use the POSIX version, -D_XOPEN_SOURCE=600 or -D_POSIX_C_SOURCE=200112L without -D_GNU_SOURCE is needed, otherwise the GNU version is preferred. */ 

注意,使用GNU扩展时要小心,最后打开( _GNU_SOURCE ),然后加入你想要影响的头文件(或者在策略上_GNU_SOURCE定义)。 不过,不用担心,如果不使用GNU扩展。

一般来说,如果GNU在默认行为中偏离了POSIX,您会在标题中看到一些注释,指出如何获得POSIX行为。 它也(通常)记录在glibc手册中,但这并不总是使高度浓缩的手册页。

编辑

试试这个简单的测试:

 #include <string.h> #ifdef _GNU_SOURCE #error "Something turned it on!" #endif 

或者更直接

 #ifdef _GNU_SOURCE #undef _GNU_SOURCE #endif #include <string.h> 

如果定义了_POSIX_C_SOURCE={version} ,那么应该有POSIX版本,除非其他情况导致GNU版本受到青睐。

我唯一能想到的就是_GNU_SOURCE 。 我敢肯定,这不是在你的命令行标志,你会看到它。 这可能是另一个包含的库已经打开了它。

这就是我所要求的POSIX实现受到青睐的扩展“棘手”的问题,即使你不是那样的人。

编辑

如果有什么东西正在打开_GNU_SOURCE (我不记得升压是否做,我不使用C ++几乎与我做C),你可能要允许它这样做。 你可以在命令行中使用--undef "[macro]" -U[macro] 。 但是,如果库代码如下所示,这将不起作用:

 #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include <stdio.h> #include <string.h> #ifdef _GNU_SOURCE #error "It didn't work" #endif int main(void) { return 0; } 

问题是,当你的代码实际上包含string.h ,其他的东西已经打开了扩展并包含了它。 包括警卫自然阻止你包括它两次。

尝试明确地关闭_GNU_SOURCE并在其他任何之前包括string.h 。 这可以防止其他库打开这些扩展。 但是,这些图书馆可能没有他们的工作。 有些代码只是“期待”GNU行为,并不包括对POSIX的回退。

我遇到过类似的库代码沮丧,没有asprintf()不起作用。

虽然标准并不要求线程安全,但我无法想象一个理智的人可以编写一个非线程安全的strerror 。 人们做什么,在运行时用gunzip错误字符串呢? 一个好的strerror应该返回一个指向标准库中字符串常量的指针,或者返回来自语言环境消息文件的常量mmap的内存。

道歉,这不是一个真正的答案,但如果你不关心绝对的理论可移植性,你可能会检查,看看是否所有你关心的实现具有理智的strerror行为,如果是这样,只是用它来代替。

这是一个特定于实现的解决方法。

 #ifdef __cplusplus extern "C" { #endif extern int __xpg_strerror_r(int errcode,char* buffer,size_t length); #define strerror_r __xpg_strerror_r #ifdef __cplusplus } #endif