【问题标题】:how are signed char and short passed as parameter in cdecl call convention在 cdecl 调用约定中,signed char 和 short 如何作为参数传递
【发布时间】:2013-12-09 18:14:02
【问题描述】:

例如

int foo(short x);
short s = -1; 
foo(s);

是一样的

//int foo(short x); //Updated
int foo(signed x);
short s = -1; 
foo((signed)s);//sign-extend and push to stack

还是一样

//int foo(short x); //Updated
int foo(unsigned)
short s = -1; 
foo((unsigned)(unsigned short)s);//zero-extend and push to stack

或者两者都可以(我们将高位视为脏)?

我可以在特殊的编译器上做一些实验。但我不确定每件事在细节上都是一样的。我只需要一些正式的承诺。

【问题讨论】:

  • 编译器实现细节有什么不同?你不应该对那些高位做任何事情,只是认为它们是未定义的。
  • @DCoder:如果您正在使用需要与 C 例程互操作的其他语言编写代码,或者您正在编写需要与其他 C 实现互操作的 C 实现,这很重要。
  • 你是说当函数原型为int foo(short x)'时,你认为大于short的数会被压入堆栈?为什么会这样?
  • @Floris:应用程序二进制接口将指定推送到堆栈的参数的最小大小,以便堆栈保持所需的对齐方式。
  • @Floris:问题是询问具体的 C 实现,而不是 C 标准。 C 标签并不意味着问题是关于 C 标准的。 “C”不仅仅意味着标准 C;除了标准之外,还有其他版本的 C。此外,有些人添加标签是因为问题涉及标记的主题,而不是因为它直接与标记的主题有关。标题特别表明问题是关于 cdecl 调用约定的。

标签: c calling-convention cdecl


【解决方案1】:

cdecl 似乎是应用程序二进制接口的不完整规范。我希望它依赖于 System V 应用程序二进制接口的完整性。我找不到明确的说明。

System V Application Binary Interface: Intel386 Architecture Processor Supplement 的第 43 页开始,“函数将所有整数值参数作为字传递,根据需要扩展或填充有符号或无符号字节和半字。”

这是模糊的,因为它没有指定参数是否应该通过符号扩展、零填充或其他方式进行扩展。我会将其解释为添加位的内容是未指定的,因此调用者可以传递任何值,而被调用者不应使用额外的位。

请注意,C 函数调用中的强制转换表达式不会对参数的传递方式产生任何影响。传递参数的类型由函数声明决定。我将您提供的示例代码解释为传递不同大小整数的概念的伪代码,而不是实际的 C 代码。

【讨论】:

  • 是的,我想我已经得到了我想要的。我的示例中确实存在一些问题。参数在传递之前可能会再次转换为short。我会更新它。谢谢。
猜你喜欢
  • 2015-04-16
  • 2012-03-17
  • 2023-03-28
  • 1970-01-01
  • 2023-03-21
  • 2014-07-09
  • 1970-01-01
  • 2012-09-03
  • 1970-01-01
相关资源
最近更新 更多