ANSI C兼容的实现是否可以在其标准库中包含其他函数?

0s0u357o  于 2023-03-22  发布在  其他
关注(0)|答案(2)|浏览(117)

ANSI C兼容的实现是否允许在其标准库中包含超出标准列举的类型和函数?(理想的答案是引用ANSI标准的相关部分。)
我特别问,因为Mac OS 10.7在stdio. h中声明了getline函数,即使在使用gcc或clang编译时使用-ansi标志。这会破坏几个定义自己的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

即使在为ANSI C89标准编译时,Mac OS 10.7中也会在stdio. h中包含getline的声明,这是一个bug吗?

2ekbmq32

2ekbmq321#

根据n1570第7.1.3节第2段(C1x草案):
不保留其他标识符。
这意味着getline不应该由<stdio.h>定义,因为根据规范,它不是保留标识符。因此,如果您的库在<stdio.h>中定义了getline,则在技术上不符合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,它会打开 * 一切 *,但我建议给那个宏一个宽的距离。

enxuqcxy

enxuqcxy2#

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

  • 所有以下划线和大写字母或另一个下划线开始的标识符始终保留用于任何用途;
  • 所有以下划线开始的标识符总是保留用作普通和标记名称空间中文件范围的标识符;
  • istostrmemwcs开始并后跟小写字母的所有外部名称;

此外,还有一些名称只有在包含某些标头时才保留;例如,如果你包含<errno.h>,那么它可以定义任何以E开头,后跟一个数字或大写字母的宏。
然而,getline() * 不是 * 这样的保留名称,并且兼容的实现必须使其可供程序员自己使用。

相关问题