4

C 语言是否保证指向不同名称的标准函数的指针必须比较不相等?

根据6.5.9 等式运算符,¶6,

两个指针比较相等当且仅当两者都是空指针,两者都是指向同一个对象(包括指向对象的指针和其开头的子对象)或函数,...

我似乎记得看到一个解释声称别名(“相同函数”的多个标识符)对于标准函数是允许的,这种处理的规范候选者是getc==fgetcand putc==fputc; 但是,我不知道我可能在哪里看到它,而且我对这个概念持怀疑态度。

是否有任何官方解释或被广泛接受的论点支持或反对这种可能性?

4

2 回答 2

0

不,我不相信有任何这样的保证。

我相信这整个讨论源于标准的一部分,该部分允许函数也被定义为具有相同名称的宏。

从 C17 7.1.4 开始:

头文件中声明的任何函数都可以额外实现为头文件中定义的类函数宏,因此如果在包含头文件时显式声明库函数,则可以使用下面显示的技术之一来确保声明不受这样一个宏的影响。函数的任何宏定义都可以通过将函数的名称括在括号中来在本地抑制,因为该名称后面没有表示宏函数名称扩展的左括号。出于相同的语法原因,即使库函数也被定义为宏189) ,也允许获取库函数的地址。


189)这意味着实现应该为每个库函数提供一个实际函数,即使它还为该函数提供了一个宏。

文本继续描述#undef如果用户想要保证他们获得实际功能,他们可以如何使用宏名称。

所以允许实现有一个标准函数和一个同名的宏。但是宏随后扩展为实现定义的。它很可能是一个内部函数,其地址与另一个库宏扩展的地址相同。

基于此,我不认为可以保证不同的功能具有不同的地址。

在特定情况下getc,标准说(C17 7.21.7.5):

getc 函数等价于 fgetc,除了如果它被实现为一个宏,它可能会计算stream不止一次,所以参数永远不应该是一个有副作用的表达式。

我会说,fgetcgetc这些被实现为宏时,实现调用相同的实际函数的可能性很大。(或者那atoistrtol调用相同的函数等)。我看过的标准库实现似乎没有这样做,但我认为标准中没有任何东西阻止它们。


(附带说明一下,由于其他原因,获取库函数的地址可能不是一个好主意,即它可能会阻止该函数在同一翻译单元内的内联。)

于 2018-10-19T08:44:09.783 回答
0

好吧,您陷入了实现细节。该标准仅指定标准库函数的行为。

对于getc规范说(强调我的):

getc 函数等价于 fgetc,除了如果它被实现为宏,它 可能会多次计算流,因此参数绝不应该是具有副作用的表达式。

因此,实现可以实现getc为宏,但也可以将其实现为别名(仅仅是指向 func 的指针)fgetc或具有相同行为的不同函数。长话短说,你不能依赖&getc == &fgetc是真的还是假的。


标准要求的唯一事情是必须根据 7.1.4 § 1 定义“&getc”:

...允许获取库函数的地址,即使它也被定义为宏...

这只是意味着实现必须具有该名称的功能,但它可以:

  • 成为fgets功能 - 好的&fgetc == &getc是真的
  • 使用宏 -fgetc == &getc是假的
  • 调用fgets函数 -&fgetc == &getc为假
于 2018-10-19T10:05:55.850 回答