相关疑难解决方法(0)

什么是严格别名规则?

当询问C中常见的未定义行为时,灵魂比我提到的严格别名规则更加开明.
他们在说什么?

c strict-aliasing undefined-behavior type-punning

778
推荐指数
10
解决办法
19万
查看次数

将结构作为其第一个成员的别名是否是严格的别名违规?

示例代码:

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++ strict-aliasing language-lawyer reinterpret-cast

23
推荐指数
2
解决办法
1079
查看次数

放置new的返回值与其操作数的转换值之间是否存在(语义)差异?

放置new的返回值与其操作数的转换值之间是否存在(语义)差异?

struct Foo { ... };
char buffer[...];

Foo *a = new(buffer) Foo;
Foo *b = reinterpret_cast<Foo *>(buffer);
Run Code Online (Sandbox Code Playgroud)

是否ab以某种方式有什么不同?


编辑:根据DaBler的评论,这个问题告诉我,如果使用const/reference成员则存在差异:使用const成员放置新类和赋值

所以,我的小位的更新问题:是否ab以任何方式不同,如果Foo没有const或引用成员?

c++ strict-aliasing placement-new language-lawyer reinterpret-cast

13
推荐指数
2
解决办法
488
查看次数

添加到"char*"指针UB,当它实际上没有指向char数组?

C++ 17(expr.add/4)说:

当向指针添加或从指针中减去具有整数类型的表达式时,结果具有指针操作数的类型.如果表达式P指向具有n个元素的数组对象x的元素x [i],则表达式P + J和J + P(其中J具有值j)指向(可能是假设的)元素x [i + j]如果0≤i+j≤n; 否则,行为未定义.同样地,如果0≤i-j≤n,则表达式P-J指向(可能是假设的)元素x [i-j]; 否则,行为未定义.

struct Foo {
    float x, y, z;
};

Foo f;
char *p = reinterpret_cast<char*>(&f) + offsetof(Foo, z); // (*)
*reinterpret_cast<float*>(p) = 42.0f;
Run Code Online (Sandbox Code Playgroud)

该行标有(*)UB?reinterpret_cast<char*>(&f)不指向char数组,而是指向浮点数,因此根据引用的段落它应该是UB.但是,如果它是UB,那么它offsetof的用处将是有限的.

是UB吗?如果没有,为什么不呢?

c++ language-lawyer

12
推荐指数
3
解决办法
392
查看次数

将char指针传递给接受char数组引用的函数

我正试图称这种方法

#define SIZE 16
void DoSomething(char(&value)[SIZE])
{
}
Run Code Online (Sandbox Code Playgroud)

从这个方法:

void BeforeDoingSomething(char* value, int len)
{
    if (len == SIZE)
    {
        DoSomething(value);
    }
}
Run Code Online (Sandbox Code Playgroud)

试图这样做会给我这个错误:

不能使用"char*"类型的值初始化类型为"char(&)[16]"(非const限定)的引用

有关如何让编译器接受value函数传递的任何提示BeforeDoingSomething

c++

10
推荐指数
1
解决办法
721
查看次数