2

假设我这样声明:

void foo(uint64_t);

而这个函数是在一个外部汇编文件中定义的。现在我从 C 代码中这样称呼它:

uint32_t x = 42;
foo(x);

什么时候x转换为 a uint64_t?我是否可以依靠我的汇编代码始终uint64_t在相关目标的 ABI 要求的任何寄存器/堆栈位置接收 a,或者我必须自己进行转换?

换句话说,当函数定义对编译器不可用时,它们是等价的吗foo(x)foo((uint64_t)x)这可能是一个愚蠢的问题,但我不确定这里到底发生了什么。

4

3 回答 3

4

显然,它永远不会 转换uint64_t,我没有看到该代码中发生任何类型转换。相反,它被提升为uint64_t是的,它总是自动发生(根据“通常的算术转换”,正如标准的措辞所说)。因此,您不需要手动投射它。

换句话说,当函数定义对编译器不可用时,它们是等价的吗foo(x)foo((uint64_t)x)

如果只有定义不可用,它们就是。但是,如果缺少声明,那就是另一回事了……(您不应该这样做!-它将调用未定义的行为,因为uint32_t将被假定为参数的类型,而事实并非如此。)

于 2013-07-13T12:46:41.470 回答
1

在 c11 规范 6.5.2.2-4 中:

在准备调用函数时,会评估参数,并为每个参数分配相应参数的值。

所以在函数调用之前x被强制转换(提升?,转换?) 。uint64_t

于 2013-07-13T12:47:08.557 回答
0

您可以避免显式类型转换,因为它会自行提升为uint64_t

编辑: @H2CO3 的回答很好地解释了这件事。

于 2013-07-13T12:56:52.773 回答