gpt4 book ai didi

c++ - 这是严格的别名违规吗?任何类型指针都可以作为字符指针的别名吗?

转载 作者:行者123 更新时间:2023-12-04 11:22:08 29 4
gpt4 key购买 nike

我仍在努力理解严格别名允许和不允许的内容。这个具体的例子是否违反了严格的别名规则?如果不是,为什么?是因为我将新的不同类型放入 char* 缓冲区吗?

template <typename T>
struct Foo
{
struct ControlBlock { unsigned long long numReferences; };
Foo()
{
char* buffer = new char[sizeof(T) + sizeof(ControlBlock)];
// Construct control block
new (buffer) ControlBlock{};
// Construct the T after the control block
this->ptr = buffer + sizeof(ControlBlock);
new (this->ptr) T{};
}
char* ptr;

T* get() {
// Here I cast the char* to T*.
// Is this OK because T* can alias char* or because
// I placement newed a T at char*
return (T*)ptr;
}
};
对于记录,void* 可以为任何其他类型的指针取别名,而任何类型指针都可以为 void* 取别名。 char* 可以为任何类型的指针设置别名,但反之是否正确?假设对齐是正确的,任何类型都可以为 char* 别名吗?那么允许以下内容吗?
char* buffer = (char*)malloc(16);
float* pFloat = buffer;
*pFloat = 6; // Can any type pointer alias a char pointer?
// If the above is illegal, then how about:
new (pFloat) float; // Placement new construct a float at pointer
*pFloat = 7; // What about now?
一旦我将 char* 缓冲区指针分配给新分配,为了将其用作浮点缓冲区,我是否需要循环遍历并在每个位置放置新的浮点数?如果我没有首先将分配分配给 char*,而是首先分配给 float*,我将能够立即将其用作浮点缓冲区,对吗?

最佳答案

Is this strict aliasing violation?


是的。

Can any type pointer alias a char pointer?


不。
您可以清洗指针:
T* get() { 
return std::launder(reinterpret_cast<T*>(ptr)); // OK
}
或者,您可以存储新的展示位置结果:
Foo()
{
...
this->ptr = new (buffer + sizeof(ControlBlock)) T{};
}
T* ptr;

T* get() {
return ptr; // OK
}

do I need to loop through and placement new a float at each place


不自议 P0593R6被语言接受(C++20)。在此之前,标准要求放置新。您不必自己编写该循环,因为标准库中有用于该循环的函数模板: std::uninitialized_fill_n , uninitialized_default_construct_n等等。此外,您可以放心,一个体面的优化器会将此类循环编译为零指令。
constexpr std::size_t N = 4;
float* pFloat = static_cast<float*>(malloc(N * sizeof(float)));

// OK since P0593R6, C++20
pFloat[0] = 6;

// OK prior to P0593R6, C++20 (to the extent it can be OK)
std::uninitialized_default_construct_n(pFloat, N);
pFloat[0] = 7;

// don't forget
free(pFloat);

附言不要使用 std::malloc在 C++ 中,除非您需要它来与需要它的 C API 交互(即使在 C 中这也是很少见的要求)。我还建议不要重复使用 new char[]缓冲,因为它对于演示的目的是不必要的。相反,使用 operator ::new它在不创建对象(甚至是微不足道的对象)的情况下分配存储。或者甚至更好,因为您已经有一个模板,让模板的用户提供他们自己的分配器,使您的模板更普遍有用。

关于c++ - 这是严格的别名违规吗?任何类型指针都可以作为字符指针的别名吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68863124/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com