|
1
6
因此,基本上,如果函数是可变的,它必须符合某种调用约定(最重要的是,调用者必须清除arg,而不是callie,因为callie不知道会有多少arg)。 它之所以在4号开始发生是因为 calling convention used on x86-64 . 据我所知,Visual C++和GCC都使用第一个参数的寄存器,然后使用堆栈。 我猜即使是可变函数也是如此(这让我觉得很奇怪,因为它会使va_*宏更复杂)。 在x86上,标准的C调用约定是始终使用堆栈。 |
|
|
2
4
问题是您正在使用size\t来表示值的类型。这是不正确的,这些值实际上是Win64上的正常32位值。 Size_t应仅用于根据平台的32位或64位大小更改大小的值(如指针)。将代码更改为使用int或_int32,这将解决您的问题。
|
|
|
3
2
一个变量函数只有弱类型检验。特别是,函数签名并没有提供足够的信息让编译器知道函数假定的每个参数的类型。 在本例中,大小\u t在Win32上为32位,在Win32上为64位。它必须像那样改变大小才能执行其定义的角色。因此,对于一个变量函数来说,要正确地提取类型为size\u t的参数,调用方必须确保编译器能够在调用模块的编译时判断出该参数是该类型的。
部分原因在于Win64中使用的实际调用约定,它似乎可以工作。从给出的示例中,我们可以看出函数的前四个整型参数是在寄存器中传递的,其余的则在堆栈中传递。这允许正确读取计数和前三个可变参数。 然而,它只是 在其他平台上,任何事情都可能发生。
在一些已知接口的情况下,可以警告类型不匹配。例如,gcc通常可以识别
|
|
|
4
2
原因是
我可以通过对所有参数进行简单转换来解决此问题,例如:
编辑: The Standard ,但这是不可能的,而且要花钱 purchase and download . 因此,我认为引用它会侵犯版权。 参考 comp.lang.c FAQ ,很明显,当编写一个函数时 variable number of arguments ,对于类型安全,您无能为力。这取决于打电话的人 make sure that each argument either perfectly matches or is explicitly cast
对于那些理解C和C的人来说,这一点应该是显而易见的
|
|
|
5
1
如果您是编写此函数的人,那么您的工作就是正确编写可变函数和/或正确记录函数的调用约定。 您已经发现C对类型的处理既快又松(另请参见signedness和promotion),因此显式转换是最明显的解决方案。这在使用UL或ULL之类的东西显式定义整数常量时常见。
最好的做法是大量记录、执行代码审查和/或编写单元测试,并记住这个bug。 |
|
|
MaPo · Linux,设置锁定ICMP_过滤器选项 1 年前 |
|
Doohyeon Won · 内联函数上的奇怪现象?[关闭] 1 年前 |
|
|
Bobby · 复合字面值总是左值吗? 1 年前 |
|
9-Pin · C: 嵌套结构的堆栈内存分配 1 年前 |