我在http://www.gnu.org/s/libc/manual/html_node/Argument-Macros.html#Argument-Macros
中阅读了在C中使用可变参数函数的方法但是,我无法理解自我推广数据类型的含义。他们是什么&它们与非自我推销数据类型有何不同?
答案 0 :(得分:4)
这是C99 standard; “自我提升”类型是那些在默认参数促销(§6.5.2.2第6段,引用§6.3.1.1中描述的整数提升)时应用它们的类型。
我对va_arg
定义(第7.15.1.1节)的解读是标准隐含了这个限制。相关部分见第2段:
[...]或 type 与实际的下一个参数的类型不兼容(如 到默认参数促销)[...]
对于正在推广的实际下一个参数的类型非常清楚,但我读到并没有说任何关于 type 被提升的内容。 (我认为“(作为提升...)”子句只是提醒一下,当调用varargs函数时,对尾随参数执行默认参数提升。)
§J.2中未定义行为列表中的此项支持此读数:
- 当没有实际的下一个参数或者使用a时,调用
va_arg
宏 指定的类型与实际的next的提升类型不兼容 参数,有一些例外(7.15.1.1)。
(虽然是的,我知道,附件J是“信息性的”而不是“规范性的”......)。
在这种情况下:va_arg(ap, float)
(例如)无效 - type 在这种情况下是float
,但实际下一个参数的提升类型不可能是float
(float
参数将被提升为double
)。
答案 1 :(得分:2)
这似乎是一个glibc限制,C标准没有。
这背后的想法是,所谓的“转换排名”小于int
的整数类型会自动提升为signed
或unsigned
int
。然后,va_arg函数会找到这样一个更广泛的参数。然后,va_arg
宏必须首先读取类型为int
的更广泛的参数,然后再将其强制转换为原始类型。
(同样适用于float
w.r.t到double
。)
对于没有意识到的程序员来说,这会产生令人惊讶的结果,所以我同意应该避免这种想法。您引用的描述似乎暗示强制不使用小型。这是假的,正如我所说,不符合标准。另一方面,如果您按照他们的建议编写代码,那么您将永远不会遇到可移植性问题,因为这是一个限制而不是扩展。