我计划在我的 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/