保证标准函数的指针不相等吗?

时间:2018-10-16 03:00:43

标签: c language-lawyer function-pointers c-standard-library

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

每个 6.5.9等式运算符,¶6,

  

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

我似乎还记得曾经看到过这样一种解释,即标准功能允许使用别名(“相同功能”的多个标识符),这种处理的规范候选为getc==fgetcputc==fputc;但是,我不知道在哪里可以看到它,我对此概念表示怀疑。

是否有官方解释或公认的论点支持或反对这种可能性?

2 个答案:

答案 0 :(得分:0)

不,我不相信有任何保证。

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

从C17 7.1.4:

  

任何   标头中声明的函数可以另外实现为定义的类似函数的宏   在标头中,因此,如果在包含标头时显式声明了库函数,则其中之一   可以使用以下所示的技术来确保声明不受此类宏的影响。任何   通过将函数名称包含在以下位置,可以局部抑制函数的宏定义   括号,因为该名称后面没有左括号,表示括号的扩展   宏函数名称。出于相同的语法原因,允许使用库的地址   函数,即使它也被定义为宏 189)

     
     

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

文字继续描述了如果用户希望保证获得实际的功能,该如何#undef宏名称。

因此,允许实现具有标准功能和具有相同名称的宏。但是宏扩展到的是实现定义的。它很可能是一个内部函数,其地址与另一个库宏扩展到的地址相同。

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

getc的特定情况下,标准规定为(C17 7.21.7.5):

  

getc函数等效于fgetc,不同之处在于,如果将其实现为宏,则它可能对stream进行多次计算,因此该参数永远不应为表达式   有副作用。

我要说的是,当实现为fgetcgetc的宏时,该实现可能会调用相同的实际函数。 (或者atoistrtol调用相同的函数,依此类推,等等)。我偷看过的标准库实现似乎不是这样,但我认为标准中没有阻止它们的任何方法。


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

答案 1 :(得分:0)

好吧,您陷入了实施细节中。该标准仅指定标准库功能的行为

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

  

getc函数等效于fgetc,不同之处在于,如果将其实现为宏,则它将   可能对流进行多次评估,因此参数不应永远不是表达式   有副作用。

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


标准唯一需要做的就是必须按照7.1.4§1定义'&getc`:

  

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

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

  • 成为fgets函数-好的&fgetc == &getc是正确的
  • 使用宏-fgetc == &getc为假
  • 调用fgets函数-&fgetc == &getc为假