【问题标题】:Function definition with an ellipsis带省略号的函数定义
【发布时间】:2019-09-01 01:40:25
【问题描述】:

我对具有可变数量参数的函数的语义有误解。 6.5.2.2(p6):

如果函数是用包含原型的类型定义的, 并且原型以省略号 (, ...) 或 提升后的参数类型与 参数的类型,行为未定义。

这不是很清楚。原型下面的函数定义中是否以省略号结尾?

void foo(int i, ...){
    //...
}

一开始我以为是参数列表只包含省略号的函数,比如

void foo(...){
    //...
}

但是这个案例是6.9.1(p8)描述的:

如果定义了一个接受可变数量参数的函数 如果没有以省略号结尾的参数类型列表,则 行为未定义

所以我真的不明白他们的意思是什么

原型以省略号 (, ...) 结尾

6.5.2.2(p6)

【问题讨论】:

    标签: c function language-lawyer ellipsis


    【解决方案1】:

    本段讨论函数调用表达式提及未看到原型的函数的情况。在这种情况下,编译器必须根据调用的参数类型来猜测其参数的类型。

    如果该函数被定义(可能在不同的翻译单元中)为可变参数,或者参数类型与编译器的猜测不匹配,则行为未定义。

    【讨论】:

    • 本段讨论了一个函数调用表达式提到了一个没有看到原型的函数的情况你能扩展一下吗?他们提到如果函数是用包含原型的类型定义的,并且原型以省略号(,...)结束。你能推荐一个6.5.2.2(p6)指定的UB示例吗?
    • 它被定义在somewhere,但不是在这个特定的调用表达式可以看到它的原型的地方。例如,在不同的源文件中。由于历史原因,C 允许在没有看到其声明的情况下突然调用函数。所以你可以写int main() { return f(1, 2); },编译器越过它的比喻,希望在某个地方可能有int f(int, int)的定义。相反,如果您在不同的源文件中定义 int f(double, double)int f(int, ...),则该调用的行为未定义。
    • 因此该函数被声明为没有原型并且可以看到声明(引用:如果表示被调用函数的表达式具有不包含原型的类型)。但定义不在范围内,在链接时提供。这就是他们想说的吗?
    • @SomeName 历史原因也允许你声明一个没有原型的函数,例如头文件中的int f(); 将匹配预期的int f(int, int) 和实际的int f(double, double) 定义。
    • “本段讨论函数调用表达式提及未看到原型的函数的情况”很好,但该段也适用于使用@987654329 对函数进行原型化的情况@
    猜你喜欢
    • 2020-05-24
    • 2013-04-12
    • 2017-03-27
    • 1970-01-01
    • 2022-07-07
    • 2012-03-26
    • 2012-12-26
    • 1970-01-01
    • 2012-02-03
    相关资源
    最近更新 更多