如何获得POSIX strerror_r而不是GNU版本? [英] How to get POSIX strerror_r instead of GNU version?

查看:990
本文介绍了如何获得POSIX strerror_r而不是GNU版本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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

编辑



在上面的手册页上,它说:

glibc的功能测试宏要求(请参阅feature_test_macros(7)):
$ b

 符合XSI的版本strerror_r ):
(_POSIX_C_SOURCE> = 200112L || _XOPEN_SOURCE> = 600)&& ! _GNU_SOURCE
否则,提供GNU特定版本。

然后在 feature_test_macros(7)

 如果没有明确定义功能测试宏,则默认定义以下功能
测试宏:_BSD_SOURCE,_SVID_SOURCE,_POSIX_SOURCE,
和_POSIX_C_SOURCE = 200809L(200112L在2.10之前的glibc版本中; 199506L在2.4美元之前的
glibc版本;在2.1之前的glibc版本中的199309L)。

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

解决方案

从头文件 string.h

  / *可重入版本的'strerror'。 
有两种`strerror_r',GNU,它返回字符串
,可能会或不可能使用提供的临时缓冲区和POSIX一个
,它将字符串填充到缓冲区中。
要使用POSIX版本,需要-D_XOPEN_SOURCE = 600或-D_POSIX_C_SOURCE = 200112L
,否则需要使用-D_GNU_SOURCE,否则GNU版本最好是
。 * /

注意,使用GNU扩展时要小心,将它们打开( _GNU_SOURCE )最后,包含您希望影响的标题(或策略性地取消定义)。通常,如果GNU在默认行为中偏离POSIX,您会在标题中看到一些注释以指示如何使用GNU扩展你可以得到POSIX的行为。它也(通常)记录在glibc手册中,但并不总是使它成为高度浓缩的手册页。


$ b 编辑



试试这个简单的测试:

  #include< string.h> ; 
#ifdef _GNU_SOURCE
#error有东西打开了它!
#endif

或者直接购买

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

如果定义 _POSIX_C_SOURCE = {version} ,你应 拥有POSIX版本,除非别的原因导致GNU版本受到青睐。



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

这就是我要求扩展在要求POSIX实现被青睐时棘手的意思,即使你不是那个让他们打开的人。



编辑

开启 _GNU_SOURCE (我不记得boost是否存在,我几乎没有像C那样使用c ++),你可能想要允许它这样做。你可以在命令行使用 - undef[macro]-U [macro] 。但是,如果库代码如下所示,那将不起作用:

  #ifndef _GNU_SOURCE 
#define _GNU_SOURCE
#endif

#include< stdio.h>
#include< string.h>

#ifdef _GNU_SOURCE
#error它不起作用
#endif

int main(void)
{
返回0;
}

问题在于,您的代码实际上包含 string.h ,其他的东西已经打开了扩展名并加入了它。包括警卫自然会阻止你将它包括两次。



尝试显式关闭 _GNU_SOURCE ,并包括 string.h 之前其他。这可以防止其他库打开这些扩展。但是,没有它们的图书馆可能无法正常工作。



我经历过类似的库代码沮丧,如果没有<$ c $就无法工作c> asprintf()。


How do I get the POSIX strerror_r instead of GNU version?

I'm compiling with g++ on Ubuntu 8.04 with glibc version 2.7 ( based on what's in ).

Edit

On the above man page it says:

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.

It then says in 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).

So I should be getting the POSIX version, but I'm getting the GNU one instead.

解决方案

From the header 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.  */

Note, be careful when using GNU extensions, turn them on (_GNU_SOURCE) last, before including the headers that you want it to affect (or undefine it strategically). No need to worry if not using GNU extensions, though.

Generally, if GNU deviates from POSIX in default behavior, you'll see some comments in the header to indicate how you can get the POSIX behavior. Its also (usually) documented in the glibc manual, but that doesn't always make it to the highly condensed man pages.

Edit

Try this simple test:

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

Or more directly

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

If _POSIX_C_SOURCE={version} is defined, you should have the POSIX version unless something else caused the GNU version to be favored.

The only thing I can think of that would do that is _GNU_SOURCE. I'm sure this isn't on your command line flags, you would have seen it. It could be that another library that is included has turned it on.

That's what I meant about the extensions being 'tricky' when requesting that POSIX implementations be favored, even if you aren't the one turning them on.

Edit

If something is turning on _GNU_SOURCE (I can't recall if boost does or not, I don't use c++ nearly as much as I do C), you probably want to allow it to do so. You can use --undef "[macro]" -U[macro] from the command line. However, that won't work if the library code looks like this:

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

The issue is, by the time your code actually includes string.h, something else has already turned on extensions and included it. Include guards naturally prevent you from including it twice.

Try explicitly turning off _GNU_SOURCE and including string.h prior to anything else. This prevents other libraries from turning those extensions on. However, those libraries might not work without them. Some code just 'expects' GNU behavior, and does not include fallback to POSIX.

I've experienced similar frustration with library code that does not work without asprintf().

这篇关于如何获得POSIX strerror_r而不是GNU版本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆