【问题标题】:Passing uint8_t instead of uint32_t into a function (in C)将 uint8_t 而不是 uint32_t 传递给函数(在 C 中)
【发布时间】:2019-04-16 15:21:22
【问题描述】:

查看一些代码(用 C 语言编写)我偶然发现了以下内容:

//we have a parameter

uint8_t num_8 = 4;

//we have a function

void doSomething(uint32_t num_32) {....}

//we call the function and passing the parameter

doSomething(num_8);

我很难理解这是否是一个正确的函数调用。这是一个强制转换还是一个错误?

一般来说,我知道在 C/C++ 语言中,只有变量的副本被传递到函数中,但是,我不确定实际发生了什么。编译器是否在堆栈上分配 32 位(用于传递的参数),将所有位归零并在复制参数之后?

谁能告诉我解释参数传递背后机制的资源?

【问题讨论】:

  • 这是一个implicit conversion
  • 您的某些答案取决于架构和过程调用标准,例如在 ARM 平台上,参数通常在 R0 中而不是在堆栈中传递。
  • 调用约定也可以不同by OS

标签: c casting


【解决方案1】:

由于函数声明包含参数类型列表,编译器知道预期参数的类型。然后它可以隐式地将实际参数转换为预期的类型。事实上,编译器处理函数调用的方式如下:

doSomething((uint32_t) num_8);

曾经使用过(不是那么)好的 K&R C 的老程序员可以记住 pre-ansi C 只有标识符列表,并且没有明确声明参数的类型。那时,我们必须显式地转换参数,而当我们忘记时,我们没有编译时警告,而是在执行时出错。

转换和调用在汇编语言或机器指令中的精确翻译方式只是一个实现细节。重要的是,一切都必须发生,就好像编译器已经声明了一个临时的 uint32_t 变量已经将 uint8_t 值强制转换为临时变量并将临时变量传递给函数一样。但是优化编译器通常使用寄存器来传递单个整数参数。根据处理器的不同,它可以将累加器归零,将单个字节加载到低位并调用函数。

【讨论】:

    猜你喜欢
    • 2020-04-15
    • 2017-06-13
    • 1970-01-01
    • 2018-10-07
    • 1970-01-01
    • 2019-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多