符合ANSI C的实现是否可以在其标准库中包含其他功能?

时间:2011-09-11 05:53:16

标签: c standards ansi osx-lion getline

符合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
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

Mac OS 10.7中的错误是否包含stdio.h中getline的声明,即使在编译ANSI C89标准时也是如此?

2 个答案:

答案 0 :(得分:12)

从n1570第7.1.3段(这是C1x的草案):

  

不保留其他标识符。

这是意味着getline不应由<stdio.h>定义的部分,因为根据规范,它不是保留的标识符。因此,如果您的图书馆在getline中定义了<stdio.h>,那么它在技术上并不符合C标准......

但是,您应该能够使用功能测试宏来导致getline<stdio.h>未定义。

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

这将只提供旧版POSIX标准的定义。这对某些GNU C ++实现不起作用,对于某些人来说这是 ExTrEmeLY fruSTRaTiNG

联机帮助页的相关部分(摘自glibc联机帮助页,抱歉......)

   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

该联机帮助页的这一部分告诉您需要将哪些宏定义到哪些值才能获得定义。我敢打赌,_POSIX_C_SOURCE已由编译器定义为200809L

功能测试宏的想法是,如果您将宏(如_POSIX_C_SOURCE_BSD_SOURCE_XOPEN_SOURCE等定义为您想要的值,则不需要担心新的库函数会与您现有的函数发生冲突。还有_GNU_SOURCE,如果您使用glibc,它会将所有内容打开,但我建议将该宏放在一个宽阔的位置。

答案 1 :(得分:4)

是的,允许兼容的实现定义其他标识符,包括函数,只要它们是标准中的保留标识符之一。例如:

  • 以下划线和大写字母或其他字母开头的所有标识符 下划线总是保留用于任何用途;

  • 所有以下划线开头的标识符始终保留用作标识符 在普通名称和标签名称空间中都有文件范围;

  • istostrmemwcs开头的所有外部名称后跟小写字母;

此外,只有在包含某些标题时才会保留名称;例如,如果您包含<errno.h>,那么它可以定义以E开头,后跟数字或大写字母的任何宏。

但是,getline() 不是这样的保留名称,并且兼容的实现必须使其可供程序员自己使用。