可变参数函数中的默认参数提升

ryy*_*ker 1 c language-lawyer

我不清楚以下摘录中使用的短语拖尾参数默认参数提升的含义,这两段似乎几乎是矛盾的,导致我不清楚何时应该预期默认提升。

ISO/IEC 9899:201x6.5.2.2函数调用

  • 第 6 段:如果表示被调用函数的表达式的类型不包含原型,...,并且具有类型的参数float被提升为double。这些被称为默认参数提升。
  • 第 7 段:“...函数原型声明符中的省略号表示导致参数类型转换在最后一个声明的参数之后停止。默认参数提升是在尾随参数上执行的。”

从第 6 段来看,(一种不包含原型的类型)似乎表明只有参数4.0并且5.0将进行默认升级。然后在段。7 它说在最后一个声明的参数之后促销停止。(我相信是b)。似乎暗示ab将进行提升,但在参数列表中跟随它们的任何内容都不会被提升。但是接下来说默认促销是对尾随参数执行的。尾随表示在 的末尾,表示省略号允许的那些。

那么在调用 f() 时到底提升了什么,为什么?

 int f(float a, float b, ...);
 
 int main(void)
 {
     float a = 1.0;
     float b = 2.0;

     int res = f(a, b, 4.0, 5.0);
     return 0;
 }

 int f(float a, float b, ...)
 {
     ...
 }
Run Code Online (Sandbox Code Playgroud)

Bar*_*mar 5

第 6 段中的任何条件都不适用于您的示例。没有原型的函数指的是使用古老的 K&R 语法声明的函数:

int f();
Run Code Online (Sandbox Code Playgroud)

当您使用这种类型的声明调用函数时,所有参数都会进行默认提升。

第 6 段还描述了其他情况,其中存在原型并且调用中的类型与原型中的类型不兼容,但您的类型是兼容的(它们是相同的)。

第7段说对前两个参数进行参数转换;它们被转换float为原型中指定的。由于ab已经float,不需要转换。

其余参数进行默认参数提升(如第 6 段所述),因为它们对应于原型中的省略号。文字4.05.0具有 type double,因此无需升级。