【发布时间】:2010-11-18 08:27:40
【问题描述】:
设置
我对在 C 中调用函数时的默认参数提升有几个问题。这是C99 standard (pdf) 中的第 6.5.2.2 节“函数调用”第 6、7 和 8 段(为方便起见,添加了重点并将其分解为列表阅读):
第 6 段
- 如果表示被调用函数的表达式的类型不包含原型,则对每个参数执行整数提升,并且类型为
float的参数提升为 @987654323 @。这些称为默认参数提升。- 如果参数的数量不等于参数的数量,则行为未定义。
- 如果函数使用包含原型的类型定义,并且原型以省略号 (
, ...) 结尾,或者提升后的参数类型与类型不兼容在参数中,行为未定义。- 如果函数定义的类型不包含原型,并且提升后的参数类型与提升后的参数类型不兼容,则行为未定义,除了对于以下情况:
- 一种提升类型是有符号整数类型,另一种提升类型是对应的无符号整数类型,并且值在两种类型中都是可表示的;
- 这两种类型都是指向字符类型或
void的限定或非限定版本的指针。
第 7 段
- 如果表示被调用函数的表达式的类型确实包含原型,则参数将隐式转换为相应参数的类型,就像通过赋值一样,采用每个参数都是其声明类型的非限定版本。
- 函数原型声明器中的省略号表示法会导致参数类型转换在最后一个声明的参数之后停止。 默认参数提升是在尾随参数上执行的。
第 8 段
- 没有隐式执行其他转换;特别是,参数的数量和类型不会与不包含函数原型声明符的函数定义中的参数的数量和类型进行比较。
我知道的
-
默认参数提升是
char和short到int/unsigned int和float到double - 可变参数函数的可选参数(如
printf)受默认参数提升的约束
郑重声明,我对函数原型的理解是这样的:
void func(int a, char b, float c); // Function prototype
void func(int a, char b, float c) { /* ... */ } // Function definition
问题
我很难理解这一切。以下是我的一些问题:
- 原型化函数和非原型化函数的行为真的差别很大吗,例如在默认提升和隐式转换方面?
- 默认参数提升何时发生?总是这样吗?或者只是在特殊情况下(比如可变参数函数)?是否取决于函数是否原型化?
【问题讨论】:
标签: c function prototype promotions