示例代码:
struct S { int x; };
int func()
{
S s{2};
return (int &)s; // Equivalent to *reinterpret_cast<int *>(&s)
}
Run Code Online (Sandbox Code Playgroud)
我认为这很常见,被认为是可以接受的.该标准确保结构中没有初始填充.但是,这种情况未在严格别名规则(C++ 17 [basic.lval]/11)中列出:
如果程序试图通过以下类型之一以外的glvalue访问对象的存储值,则行为未定义:
- (11.1)对象的动态类型,
- (11.2)对象的动态类型的cv限定版本,
- (11.3)与对象的动态类型类似(如7.5中所定义)的类型,
- (11.4)与对象的动态类型对应的有符号或无符号类型的类型,
- (11.5)一种类型,它是有符号或无符号类型,对应于对象动态类型的cv限定版本,
- (11.6)聚合或联合类型,包括其元素或非静态数据成员中的上述类型之一(递归地,包括子聚合或包含联合的元素或非静态数据成员),
- (11.7)一种类型,它是对象的动态类型的(可能是cv限定的)基类类型,
- (11.8)char,unsigned char或std :: byte类型.
很明显,对象s正在访问其存储值.
项目符号点中列出的类型是执行访问的glvalue的类型,而不是被访问对象的类型.在这段代码中,glvalue类型int不是聚合类型或联合类型,排除了11.6.
我的问题是:这个代码是否正确,如果是,那么允许上述哪一个要点?
我和一位同事正试图实现一个简单的多态类层次结构.我们正在研究嵌入式系统,仅限于使用C编译器.我们有一个基本的设计思想,在没有警告的情况下编译(-Wall -Wextra -fstrict-aliasing -pedantic),并且在gcc 4.8.1下运行正常.
但是,我们有点担心别名问题,因为我们还不完全理解这会成为问题.
为了演示我们已经编写了一个带有"接口"IHello的玩具示例和两个实现此接口'Cat'和'Dog的类.
#include <stdio.h>
/* -------- IHello -------- */
struct IHello_;
typedef struct IHello_
{
void (*SayHello)(const struct IHello_* self, const char* greeting);
} IHello;
/* Helper function */
void SayHello(const IHello* self, const char* greeting)
{
self->SayHello(self, greeting);
}
/* -------- Cat -------- */
typedef struct Cat_
{
IHello hello;
const char* name;
int age;
} Cat;
void Cat_SayHello(const IHello* self, const char* greeting)
{
const Cat* cat = (const Cat*) self;
printf("%s I …Run Code Online (Sandbox Code Playgroud) 这是一个严格的别名问题,因为编译器会因此引起任何优化顺序问题。
假设我float在一个中有三个public struct XMFLOAT3(与这个不同)。我想强制转换成一个float*。这会使我陷入优化麻烦吗?
XMFLOAT3 foo = {1.0f, 2.0f, 3.0f};
auto bar = &foo.x;
bar[2] += 5.0f;
foo.z += 5.0f;
cout << foo.z;
Run Code Online (Sandbox Code Playgroud)
我认为这将始终打印“ 13”。但是这段代码呢:
XMFLOAT3 foo = {1.0f, 2.0f, 3.0f};
auto bar = reinterpret_cast<float*>(&foo);
bar[2] += 5.0f;
foo.z += 5.0f;
cout << foo.z;
Run Code Online (Sandbox Code Playgroud)
我认为这是合法的,因为根据http://en.cppreference.com/w/cpp/language/reinterpret_cast#Type_aliasing
T2是聚合类型或联合类型,其将上述类型之一作为元素或非静态成员(递归地包括子聚合的元素和所包含的联合的非静态数据成员):这样可以安全地进行强制转换从结构的第一个成员到联合的元素,再到包含它的结构/联合。
我对此的理解正确吗?
显然,这将成为依赖的声明的实现XMFLOAT3。
请向我解释包含变量i初始化的行
struct vector
{
float value;
};
int main()
{
vector v3;
v3.value = 5.0f;
float i = *(float*)&(v3);
return 0;
}
Run Code Online (Sandbox Code Playgroud)