c - "Strong"通过单元素结构输入 C。编译器会做什么?

标签 c struct padding strong-typing c89

我计划在我的 C 代码中使用包含标量字段的结构来执行一些语义强类型化。基本思想是用于廉价“操作”的宏,它将在错误命名的结构字段上失败,当然还有严格参数列表的更复杂的函数。

示例(只有基本的想法 - 不是特别聪明的宏代码)

typedef struct {float32_t speedval} MySpeed_t;
typedef struct {float32_t timeval} MyTime_t;
typefed struct {float32_t accvalue} MyAcceleration_t;

#define ACC_VEL_DT(acc,vel,time)\
          (((acc).accvalue = (vel).speedval / (time).timeval)), (acc))

#define ADD_SPEED(velres, vel1, vel2) \
           (((velres).speedval = (vel1).speedval + (vel2).speedval), (velres))

unint8 someCleverMathAndCheck(MySpeed_t speed, MySpeed_t speedArr[], MyAcceleration_t);

现在,在处理此类单元素结构时,我对编译器有什么期望?当使用这些结构作为函数参数时,我是否必须期待一些填充、用于“取消引用第一个元素”的更复杂的 asm 或可怕的事情?该标准说明了什么?

最佳答案

不会有任何额外的填充。根据标准,结构的地址是其第一个元素的地址,因此填充总是插入元素之间或结构的末尾,而不是开头。此外,您不必担心末尾的额外填充,因为对齐方式将完全符合(单一)数据类型所需的对齐方式。

启用优化后,您可以期望编译器生成基本相同的汇编代码。例如,O2 的(32 位)GCC 生成的代码用于:

float add(float a, float b)
{
    return a + b;    
}

看起来像:

_add:
LFB0:
    .cfi_startproc
    flds    8(%esp)
    fadds   4(%esp)
    ret
    .cfi_endproc

如果您改为定义如下内容:

typedef struct foo
{
    float x;
} foo;

foo add(foo a, foo b)
{
    foo f; 
    f.x = a.x + b.x;
    return f;
}

然后用O2编译,程序集完全一样。

关于c - "Strong"通过单元素结构输入 C。编译器会做什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25074706/

相关文章:

c - 使用指针运算来更改另一个函数中变量的值。

c - 如何从 c 调用 opaque_wrapper 结构?

C:为什么可以按值传递(给函数)结构,而不是数组?

c - 结构标签

c++ - 具有私有(private)成员的结构的构造函数

css - 为什么不考虑此 <DIV> 的填充(在底部)?

c - 没有收到 WM_DISPLAYCHANGE

java - 具有单个表的 DynamoDB 中的最大值二级索引键?

html - 如何使用 em 而不是 px 更改 <h1> 到 <h6> 以具有与 <p> 相同的填充,同时保持它们完全相同?

带有边距和填充的 Android 权重