【发布时间】:2018-06-01 17:01:11
【问题描述】:
我看到 C++17 引入了带有 std::align_val_t 的对齐新表达式,用于需要比 new 自然提供的更大对齐的对象。这很棒,但让我思考:
为什么指针对齐不是指针类型的一部分?
例如:
long foo(long *x) {
return *x; // here, the compiler do an aligned load
// correct as (long*) is expected to be aligned
}
假设指针在 64 位上对齐(在我的机器上)。 但如果我执行以下操作,编译器不会警告我:
long bar(char *x) {
return foo((long*) x); // here, the compiler do an aligned load, risky!
}
long pop(char *z) {
return bar(z + 1); // here, the compiler do an aligned load too!
}
我通过从打包结构中传递一个指向字段的指针来得到警告:
struct ugly {
char x;
long y;
} __attribute__((packed));
long kun(ugly *a) {
return a->y; // here, the compiler do an unaligned load, correct!
}
long zip(ugly *a) {
return foo(&a->y); // here, the compiler do an aligned load, incorrect!
// but warns me about it.
}
但为什么不是错误,类似于const_cast?
标准对对齐有何规定?
是否所有编译器都在做不正确的假设,或者是未定义/实现定义的行为来提供指向函数的未对齐指针?
您可以在此处查看它们的实际效果:https://godbolt.org/g/9ddbiq
编辑:修复了sn-p代码,并提供了godblot链接。
【问题讨论】:
-
它可能是特定于实现的(和 UB)。对齐在ABI 级别很重要,不仅在语言级别
-
您的示例不是合法的 c++。它不会编译,因为不能将
void*分配给long*,也不能将3分配给long*。此外,您似乎正在尝试取消引用设置为地址 3 的指针。 -
对于这个问题,我们真的需要minimal reproducible example,可能带有指向godbolt.org上示例的链接
标签: c++ compiler-errors