C 函数参数转换何时完成?

C 函数参数转换何时完成?,c,arguments,type-conversion,C,Arguments,Type Conversion,假设我这样声明: void foo(uint64_t); 此函数在外部程序集文件中定义。现在我用C代码这样称呼它: uint32_t x = 42; foo(x); 何时将x转换为uint64\u t?我可以依靠我的汇编代码始终在相关目标的ABI要求的任何寄存器/堆栈位置接收uint64\t,还是我必须自己执行强制转换 换句话说,当编译器无法使用函数定义时,foo(x)和foo((uint64_t)x)是否等效?这可能是一个愚蠢的问题,但我不确定这里到底发生了什么。显然,它从未被转换为uin

假设我这样声明:

void foo(uint64_t);
此函数在外部程序集文件中定义。现在我用C代码这样称呼它:

uint32_t x = 42;
foo(x);
何时将
x
转换为
uint64\u t
?我可以依靠我的汇编代码始终在相关目标的ABI要求的任何寄存器/堆栈位置接收
uint64\t
,还是我必须自己执行强制转换


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

显然,它从未被转换为
uint64\u t
,我没有看到在该代码中发生任何类型转换。相反,将其提升为
uint64\u t
,是的,它总是自动发生(按照标准的措辞,根据“常用算术转换”)。因此,您不需要手动施放。

换句话说,当编译器无法使用函数定义时,
foo(x)
foo((uint64_t)x)
是否等效


如果只有定义不可用,则它们是可用的。如果声明丢失,那就不同了。。。(您不应该这样做!-它将调用未定义的行为,因为
uint32\u t
将被假定为参数的类型,而事实并非如此。)

在c11规范6.5.2.2-4中:

在准备调用函数时,将计算参数,并为每个参数指定相应参数的值


因此,在函数调用之前,
x
被强制转换(升级?、转换?)为
uint64\u t

您可以避免显式地对其进行类型转换,因为它将自身升级为
uint64\u t

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

不,它从来没有“铸造过”。它被提升了。事实上,它从来都不是演员@H2CO3它是“已转换的”,而不是“已升级的”。是的,声明本身始终存在-但函数是在汇编中编写的,因此编译器通常无法使用函数的定义。谢谢,这很有道理:)@Thomas不客气。声明总是足够的。这就是声明的目的。(如果编译器需要这个定义,那将是一个非常糟糕的混乱!)仅就词汇表而言,用C标准术语来说,这实际上不是“升级”,而是“转换”。“整数提升”是在范围中没有原型时有效的规则,狭义类型被提升为
int
之类的东西。我编辑了词汇表的标题。在C标准术语中,强制转换是一种“显式转换”。似乎您只是要求进行“隐式转换”。函数参数发生的是转换,而不是升级<代码>无效f(整数x);f(1LL)导致
1LL
转换为
int
,但从
long
转换为
int
几乎不是一种“提升”。