相关疑难解决方法(0)

什么是严格别名规则?

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

c strict-aliasing undefined-behavior type-punning

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

如何使用指向自定义分配器(无 UB)提供的原始内存的指针?

我正在尝试编写一个分配器感知容器。假设我想为三个对象分配一块内存:

T* chunk = std::allocator_traits<Allocator>::allocate(allocator, 3);
Run Code Online (Sandbox Code Playgroud)

(我知道分配器可以有自定义指针类型,因此我应该使用std::allocator_traits<Allocator>::pointer;为了简单起见,我在这里使用原始指针。)

现在我想在索引 2 处创建一个实际对象。我该怎么做?特别是,如何计算指向尚不存在的元素的指针?最明显的选项如下:

std::allocator_traits<Allocator>::construct(allocator, chunk + 2, ...);
Run Code Online (Sandbox Code Playgroud)

不幸的是,chunk + 2似乎并不正确:根据标准,指针运算只能对指向数组元素的指针执行,否则会导致未定义的行为。出于同样的原因,我无法将指针转换为指针std::byte*并对其使用指针算法。(虽然std::allocator定义为在新分配的内存中创建数组,但在 C++20 之前,自定义分配器不存在相同的要求。此外,虽然 C++20 增加了一些“隐式创建对象”的语言,但这并没有申请较早的 C++ 版本。)

那么如何计算要作为第二个参数给出的指针construct而不导致未定义的行为(在 C++20 之前)?

c++ undefined-behavior allocator language-lawyer c++17

5
推荐指数
1
解决办法
193
查看次数

如果没有 constexpr std::uninitialized_copy,std::vector 如何能够成为 constexpr?

我正在实现我自己的容器,并且我试图使其尽可能对 constexpr 友好。

\n

在这个过程中,我发现这std::uninitialized_copy不是 constexpr,因此我无法使用标准算法实现复制分配。

\n

然而, constexprstd::vector 是否友好:

\n
constexpr auto f() {\n    std::vector<int> v = {1, 2, 3};\n    return v.size();\n}\n\nstatic_assert(f() == 3);\n
Run Code Online (Sandbox Code Playgroud)\n

当我替换为我自己的容器时,我无法实现此目的std::vector。\n我收到错误:

\n
... error: call to non-\xe2\x80\x98constexpr\xe2\x80\x99 function \xe2\x80\x98_ForwardIterator std::uninitialized_copy(_InputIterator, ...\n
Run Code Online (Sandbox Code Playgroud)\n

我想知道标准库(例如 stdlib)如何实现这一点。\n它是否使用uninitialized_copyconstexpr 的秘密实现?\nconstexpr uninitalized_copy 是否可以实现?

\n

我想挑战在于拥有constexpr addressofconstexpr construct_at。\n是否有一个我可以回退的实现?

\n

c++ initialization std constexpr

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

i++ + ++i 是怎么回事?

所以我一直在读一本 C++14 书(这是我图书馆最新的一本),尽管我比它深了大约 100-200 页,但有些东西一直在我的脑海中游动,但在某些时候它提到了这一点打脸:

i++ + ++i;
Run Code Online (Sandbox Code Playgroud)

它说不要这样做,但我还是这样做了。在 Visual Studio C++ 和在线 C++ 编译器(特别是 onlinegdb)中,它给我3when int i = 1;,但是当我分配 时i = i++ + ++i;,在线编译器给我4,Visual Studio 给我5......让我们看看, ifi++递增i但 是原始值,并且++i递增i和是新的和改进的 i,那么如果int i = 1;,我们会这样做:

1 + 2;
Run Code Online (Sandbox Code Playgroud)

并且i会是3!两个编译器都这么说。 i = i++ + ++i;给出了不同的答案!我希望我可以验证这一点,但我无法在脑海中计算分配和增量。也许这就是编译器正在做的事情,一个在表达式中分配然后递增,另一个则做相反的事情。PEMDAS 与 PEDMAS 的精神对比。

所以我知道这是未定义行为的字面教科书示例,但无论如何我都会问一个问题:在实践中是否有未定义行为 的使用,是否有充分的理由使用这段特定的代码(可能没有)因为它的可怕性质),关于这段代码(及其交易)还有什么需要注意的吗?

c c++ undefined-behavior

-4
推荐指数
1
解决办法
176
查看次数