符合 ANSI C 的实现能否在其标准库中包含附加功能? [英] Can an ANSI C-compliant implementation include additional functions in its standard library?

查看:29
本文介绍了符合 ANSI C 的实现能否在其标准库中包含附加功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否允许符合 ANSI C 的实现在其标准库中包含除标准列举的类型和函数之外的其他类型和函数?(理想的答案是参考 ANSI 标准的相关部分.)

我特别问,因为 Mac OS 10.7 在 stdio.h 中声明了 getline 函数,即使在使用 -ansi 标志使用 gcc 或 clang 进行编译时也是如此.这打破了几个定义自己的 getline 函数的旧程序.这是 Mac OS 10.7 的错吗?(Mac OS 10.7 上 getline 的手册页说 getline 符合 2008 年推出的 POSIX.1 标准.)

澄清一下,我觉得奇怪的是,在 Mac OS 10.7 上的 ANSI C89 程序中包含 stdio.h 也会引入 getline 函数的声明,因为 getline 不是 stdio.h 的 K&R(大概是 ANSI)描述中列举的函数之一.特别是,尝试编译 noweb:

gcc -ansi -pedantic -c -o notangle.o notangle.c在 notangle.nw:28 包含的文件中:getline.h:4: 错误:getline"的类型冲突/usr/include/stdio.h:449: 错误:'getline' 的先前声明在这里

Mac OS 10.7 中的 bug 是否包括 stdio.h 中的 getline 声明,即使在针对 ANSI C89 标准进行编译时?

解决方案

来自 n1570 的第 7.1.3 节第 2 段(这是 C1x 的草案):

<块引用>

不保留其他标识符.

这部分意味着 getline 不应由 定义,因为它不是规范中的保留标识符.因此,如果您的库在 <stdio.h> 中定义了 getline,则它在技术上不符合 C 标准...

但是,您应该能够使用功能测试宏来导致 getline 中未定义.

#undef _POSIX_C_SOURCE#define _POSIX_C_SOURCE 200112L#include 

这将只为您提供旧 POSIX 标准的定义.这不适用于某些 GNU C++ 实现,这对某些人来说非常令人沮丧.

手册页的相关部分是(取自 glibc 手册页,抱歉...)

<前>glibc 的功能测试宏要求(请参阅 feature_test_macros(7)):getline(), getdelim():从 glibc 2.10 开始:_POSIX_C_SOURCE >= 200809L ||_XOPEN_SOURCE >= 700在 glibc 2.10 之前:_GNU_SOURCE

手册页的这一部分告诉您需要将哪些宏定义为哪些值才能获得定义.我敢打赌 _POSIX_C_SOURCE 已经被你的编译器定义为 200809L.

功能测试宏的想法是,如果你定义你的宏,比如 _POSIX_C_SOURCE_BSD_SOURCE_XOPEN_SOURCE 等等您希望,您无需担心新库函数与现有函数发生冲突.还有 _GNU_SOURCE,如果你使用 glibc,它会打开一切,但我建议给这个宏一个很大的泊位.

Is an ANSI C-compliant implementation allowed to include additional types and functions in its standard library, beyond those enumerated by the standard? (An ideal answer would reference the relevant part of the ANSI standard.)

I ask particularly because Mac OS 10.7 declares the getline function in stdio.h, even when compiling with gcc or clang using the -ansi flag. This breaks several older programs that define their own getline function. Is this a fault of Mac OS 10.7? (The man page for getline on Mac OS 10.7 says that getline conforms to the POSIX.1 standard, which came in 2008.)

Edit: To clarify, I find it odd that including stdio.h in an ANSI C89 program on Mac OS 10.7 also pulls in the declaration for the getline function, since getline is not one of the functions enumerated in the K&R (and presumably ANSI) description of stdio.h. In particular, attempting to compile noweb:

gcc -ansi -pedantic    -c -o notangle.o notangle.c
In file included from notangle.nw:28:
getline.h:4: error: conflicting types for ‘getline’
/usr/include/stdio.h:449: error: previous declaration of ‘getline’ was here

Is it a bug in Mac OS 10.7 includes the declaration of getline in stdio.h even when compiling for the ANSI C89 standard?

解决方案

From section 7.1.3 paragraph 2 of n1570 (which is a draft of C1x):

No other identifiers are reserved.

This is the part that means getline shouldn't be defined by the <stdio.h>, since it's not a reserved identifier according to the spec. So if your library defines getline in <stdio.h>, it's not technically compliant with the C standard...

However, you should be able to use the feature test macros to cause getline to be undefined in <stdio.h>.

#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200112L
#include <stdio.h>

This will give you only the definitions from the older POSIX standards. This won't work on some GNU C++ implementations, which is ExTrEmeLY fruSTRaTiNG for some folks.

The relevant section of the manpage is (taken from a glibc manpage, sorry...)

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       getline(), getdelim():
           Since glibc 2.10:
               _POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700
           Before glibc 2.10:
               _GNU_SOURCE

This part of the manpage tells you which macros need to be defined to which values in order to get the definition. My bet is that _POSIX_C_SOURCE is already defined by your compiler to 200809L.

The idea of feature test macros is that if you define your macros, like _POSIX_C_SOURCE, _BSD_SOURCE, _XOPEN_SOURCE, etc. to the values you want, you won't need to worry about new library functions clashing with your existing functions. There is also _GNU_SOURCE, which turns everything on if you use glibc, but I suggest giving that macro a wide berth.

这篇关于符合 ANSI C 的实现能否在其标准库中包含附加功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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