相关疑难解决方法(0)

通过将对象指针转换为`char *`,然后执行`*(member_type*)(pointer + offset)`来访问成员是否是UB?

下面是一个例子:

#include <cstddef>
#include <iostream>

struct A
{
    char padding[7];
    int x;
};
constexpr int offset = offsetof(A, x);

int main()
{
    A a;
    a.x = 42;
    char *ptr = (char *)&a;
    std::cout << *(int *)(ptr + offset) << '\n'; // Well-defined or not?
}
Run Code Online (Sandbox Code Playgroud)

我一直认为它是明确定义的(否则有什么意义offsetof),但不确定。

最近有人告诉我它实际上是UB,所以我想一劳永逸地弄清楚。

上面的例子是否会导致UB?如果将类修改为非标准布局,是否会影响结果?

如果是 UB,是否有任何解决方法(例如申请std::launder)?


整个主题似乎都没有实际意义且没有具体说明。

以下是我能找到的一些信息:

c++ language-lawyer

9
推荐指数
2
解决办法
378
查看次数

实现一个没有未定义行为的std :: vector like容器

它可能会让一些程序员感到惊讶,并且尽管可能令人惊讶,但如果没有std::vector编译器的非标准支持,则无法实现.问题基本上在于能够在原始存储区域上执行指针运算.论文,p0593:出现在@ShafikYaghmour答案中的低级对象操纵对象的隐式创建,清楚地揭示了问题,并提出修改标准,以便更容易实现像容器和其他法律级编程技术的矢量.

然而,我想知道是否没有工作来实现一个类型,std::vector只相当于使用语言提供的内容而不使用标准库.

目标是在原始存储区域中逐个构造向量元素,并能够使用迭代器访问这些元素.这相当于std :: vector上的push_back序列.

为了解问题,请简单介绍std::vector在libc ++或libstdc ++ 中执行的操作:

void access_value(std::string x);

std::string s1, s2, s3;
//allocation
auto p=static_cast<std::string*>(::operator new(10*sizeof(std::string)));

//push_back s1
new(p) std::string(s1);
access_value(*p);//undefined behavior, p is not a pointer to object

//push_back s2
new(p+1) std::string(s2);//undefined behavior
        //, pointer arithmetic but no array (neither implicit array of size 1)
access_value(*(p+1));//undefined behavior, p+1 is not a pointer to object

//push_back s2
new(p+2) std::string(s3);//undefined behavior
        //, pointer arithmetic but no array …
Run Code Online (Sandbox Code Playgroud)

c++ memory-management undefined-behavior language-lawyer

2
推荐指数
1
解决办法
196
查看次数