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

时间:2021-01-04 00:14:59

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.)

是否符合ANSI C标准的实现允许在其标准库中包含其他类型和功能,除了标准列举的那些之外? (理想的答案将参考ANSI标准的相关部分。)

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.)

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

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:

编辑:为了澄清,我发现奇怪的是,在Mac OS 10.7上的ANSI C89程序中包含stdio.h也会引入getline函数的声明,因为getline不是K&R中枚举的函数之一(可能是ANSI) stdio.h的描述。特别是,尝试编译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?

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

2 个解决方案

#1


12  

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

从n1570第7.1.3段(这是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...

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

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

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

#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.

这将只提供旧POSIX标准的定义。这对某些GNU C ++实现不起作用,对于某些人来说这是非常糟糕的结果。

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

联机帮助页的相关部分(摘自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

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.

该联机帮助页的这一部分告诉您需要将哪些宏定义到哪些值才能获得定义。我敢打赌,_POSIX_C_SOURCE已经由编译器定义为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 *ing 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.

功能测试宏的想法是,如果您将宏(如_POSIX_C_SOURCE,_BSD_SOURCE,_XOPEN_SOURCE等)定义为所需的值,则无需担心与现有功能冲突的新库函数。还有_GNU_SOURCE,如果你使用glibc,它会打开所有东西,但我建议给那个宏一个广泛的位置。

#2


4  

Yes, a compliant implementation is allowed to define additional identifiers, including functions, as long as they are one of the reserved identifiers in the standard. For example:

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

  • All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use;

    所有以下划线开头的标识符以及大写字母或另一个下划线始终保留用于任何用途;

  • All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces;

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

  • All external names that begin with is, to, str, mem or wcs followed by a lowercase letter;

    所有外部名称都以,to,str,mem或wcs后跟小写字母;

In addition there are names that are reserved only if you include certain headers; for example, if you include <errno.h> then it can define any macro starting with E followed by a digit or uppercase letter.

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

However, getline() is not such a reserved name, and a compliant implementation must make it available for the programmer's own use.

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

#1


12  

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

从n1570第7.1.3段(这是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...

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

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

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

#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.

这将只提供旧POSIX标准的定义。这对某些GNU C ++实现不起作用,对于某些人来说这是非常糟糕的结果。

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

联机帮助页的相关部分(摘自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

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.

该联机帮助页的这一部分告诉您需要将哪些宏定义到哪些值才能获得定义。我敢打赌,_POSIX_C_SOURCE已经由编译器定义为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 *ing 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.

功能测试宏的想法是,如果您将宏(如_POSIX_C_SOURCE,_BSD_SOURCE,_XOPEN_SOURCE等)定义为所需的值,则无需担心与现有功能冲突的新库函数。还有_GNU_SOURCE,如果你使用glibc,它会打开所有东西,但我建议给那个宏一个广泛的位置。

#2


4  

Yes, a compliant implementation is allowed to define additional identifiers, including functions, as long as they are one of the reserved identifiers in the standard. For example:

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

  • All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use;

    所有以下划线开头的标识符以及大写字母或另一个下划线始终保留用于任何用途;

  • All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces;

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

  • All external names that begin with is, to, str, mem or wcs followed by a lowercase letter;

    所有外部名称都以,to,str,mem或wcs后跟小写字母;

In addition there are names that are reserved only if you include certain headers; for example, if you include <errno.h> then it can define any macro starting with E followed by a digit or uppercase letter.

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

However, getline() is not such a reserved name, and a compliant implementation must make it available for the programmer's own use.

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