va_arg 中的铸造方式

Way of casting in va_arg

我正在研究可变参数函数和参数。

我注意到 va_arg 能够将对象转换为其他对象。例如,当下一个参数是 char,但你使用的 va_arg 就像它应该是 int,它会将 char 转换为 int :

函数调用:

AddNumbers(3, 5, 'a', 20);

函数声明:

int AddNumbers(int count, ...) {
    int result;

    va_list va;
    va_start(va, count);
    for(int i = 0; i < count; ++i) {
        result += va_arg(va, int);
    }
    return result;
}

所以我的问题是:这个函数使用了什么样的类型转换(C 风格、dynamic_cast 等)?

如果我正确理解你的问题:

C 在调用可变参数函数时默认执行某些 "casts"。 GCC 调用这些 default argument promotions。他们是:

  • 有符号或无符号 charshort int 变为有符号或无符号 int
  • float 变为 double.

这真的不是 va_arg AddNumbers 中进行转换的问题;相反,在调用 AddNumbers 时,调用者将参数提升为 AddNumbers 作为将它们推入堆栈以供 AddNumbers 使用的一部分。

与选角无关。在这种情况下,它起作用是因为参数 promotion.

当您使用可变参数函数时,integer types smaller than int (like e.g. char) are promoted to int

这就是它在将字符文字传递给函数时起作用的原因。如果您尝试其他类型,例如一个浮点值,那么它将不再起作用。

至于什么va_arg macro (it's mostly implemented as a macro) does, it is totally implementation dependent. It might not do any casting at all, but use some other form of type punning代替。

不完全是转换,因为va_arg是宏,不是函数。所以va_arg(va, int)的类型是构造int.

但是 提升 确实会在调用可变参数函数时发生(省略号前面的参数除外。

所以在AddNumbers(3, 5, 'a', 20);中,字符'a'被提升为一个int。然后,您可以像代码一样将它用作 int,或者将其转换回 char(转换不是强制转换),因为 int 值可以表示为 char(通过构造)