【问题标题】:Guarantee of non-equality of pointers to standard functions?保证指向标准函数的指针不相等?
【发布时间】:2019-03-20 12:12:39
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 我怀疑strtoll(),strtoimax() 可能是getc()/fgetc()
  • 注意:C 规范有“允许获取库函数的地址,即使它也被定义为宏。” §7.1.4 1 - 不是该规范在这里应用太多,但确实讨论了“库函数的地址”注意,脚注说“这意味着实现应为每个库函数提供一个实际函数,即使它还提供该功能的宏。” - 嗯。
  • 还有 6.9.5:“如果用外部链接声明的标识符在表达式中使用......在整个程序的某个地方,该标识符应该只有一个外部定义”,以及 7.1。 2.6:“库函数的任何声明都应具有外部链接”。如果getc 别名为fgetc,那么我想是否存在“[前] 标识符的外部定义”是值得商榷的。
  • 我怀疑“保证指向不同名称的标准函数的指针必须比较不相等”是错误的。我对规范的审查没有发现这样的退休,但我认为要很好地回答你的问题需要更多的时间。祝你好运。
  • 无论标准可能会或可能不会说,experimentation 表明至少在某些实现中,&fgetc == &getc 评估为 true。

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


【解决方案1】:

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

我相信整个讨论源于标准中允许将函数定义为同名宏的部分。

从 C17 7.1.4 开始:

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


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

文字继续描述用户如何#undef 宏名称,如果他们想保证他们得到一个实际的功能。

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

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

getc 的具体情况下,标准说 (C17 7.21.7.5):

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

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


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

【讨论】:

    【解决方案2】:

    你陷入了实现细节。标准只规定了标准库函数的行为

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

    getc 函数与 fgetc 等价,只是如果它被实现为宏,它 可能多次评估流,因此参数不应永远不是表达式 有副作用。

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


    标准要求的唯一条件是 '&getc` 必须按照 7.1.4 § 1 进行定义:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-24
      • 2011-04-26
      • 1970-01-01
      相关资源
      最近更新 更多