假设我声明如下:
void foo(uint64_t);
此函数在外部程序集文件中定义。现在我从C代码中这样称呼它:
uint32_t x = 42;
foo(x);
x
何时投放到uint64_t
?我可以依赖我的汇编代码总是在相关目标的ABI规定的任何寄存器/堆栈位置接收uint64_t
,还是我必须自己进行投射?
换句话说,当函数定义对编译器不可用时,foo(x)
和foo((uint64_t)x)
是等价的吗?这可能是一个愚蠢的问题,但我不确定这里到底发生了什么。
答案 0 :(得分:4)
显然,从不 投射到uint64_t
,我在该代码中看不到任何类型转换。相反,它是提升到uint64_t
,是的,它总是自动发生(根据“通常的算术转换”,正如标准的措辞一样)。因此,您无需手动投射。
换句话说,当函数定义对编译器不可用时,
foo(x)
和foo((uint64_t)x)
等效吗?
如果只有定义不可用,那就是它们。如果缺少声明,那就是另一个故事......(你不应该这样做! - 它将调用未定义的行为,因为uint32_t
将被假定为这个论点,它不是。)
答案 1 :(得分:1)
在c11规范6.5.2.2-4中:
在准备对函数的调用时,将计算参数,并为每个参数分配相应参数的值。
所以x
在函数调用之前被转换(提升?,转换?)到uint64_t
。
答案 2 :(得分:0)
您可以避免明确对其进行类型转换,因为它将提升本身转移到uint64_t
修改强> @ H2CO3的answer解释了这件事。