Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
std::memcpy即使在C++20中也不是constexpr的原因是什么?_C++_Constexpr_C++20 - Fatal编程技术网

std::memcpy即使在C++20中也不是constexpr的原因是什么?

std::memcpy即使在C++20中也不是constexpr的原因是什么?,c++,constexpr,c++20,C++,Constexpr,C++20,我知道在编译时复制任意内存块并不总是可能的,但既然我们得到了constexpr constainer、虚拟方法和算法,为什么不也使用memcpy呢?这也是一种算法 此外 C++20 std::bit_cast看起来很像std::memcpy工作区reinterpret_cast,但它是constexpr。 对于C++20,使用迭代器复制被标记为constexpr,因此复制类型在某种程度上是可能的。 其用途是复制或只是重新解释constexpr函数中的变量/数组,std::bit_cast AFA

我知道在编译时复制任意内存块并不总是可能的,但既然我们得到了constexpr constainer、虚拟方法和算法,为什么不也使用memcpy呢?这也是一种算法

此外

C++20 std::bit_cast看起来很像std::memcpy工作区reinterpret_cast,但它是constexpr。 对于C++20,使用迭代器复制被标记为constexpr,因此复制类型在某种程度上是可能的。 其用途是复制或只是重新解释constexpr函数中的变量/数组,std::bit_cast AFAIK无法解决前者。特别是,我的答案和我想使用它

为什么std::bit_cast可以是constexpr而std::memcpy不能是constexpr,有什么特别的原因吗? 这与使用void指针而不是类型化引用的memcpy有关吗? 实际上不需要复制任何东西? C向后兼容性? 可能是因为不支持指向constexpr内存的指针?但这同样适用于std::bit_cast中的引用参数和std::copy中的迭代器。 从某处简要引用的相关答案:

此外,目前还不可能实现constexpr 位转换函数,因为memcpy本身不是constexpr。标记 建议的函数作为constexpr不需要或阻止memcpy 成为constexpr,但需要编译器支持。这只剩下 实现可以自由使用自己的内部解决方案,例如LLVM 比特广播操作码

但它并没有详细说明不让它也成为constexpr


请注意,我并没有询问std::bit_cast存在的原因。我喜欢它,它提供了一个明确的意图,而不是std::memcpy解决方案。

这更多的是一个评论,而不是一个答案,因为我只是引用了其中的内容,但我在这里写它,因为它不符合评论:

B.std::memmove和std::memcpy必须添加constexpr std::memmove和std::memcpy接受void*和const void*参数。这使得在纯C++中不可能实现为conExPR,因为常量表达式不能根据[Exp.const ]来评估从类型CV空隙*到指针类型到对象类型的转换。 然而,这些函数不仅很流行,而且在标准库中广泛使用,以获得更好的性能。不让它们成为constexpr将迫使标准库开发人员为它们提供编译器内部函数。这是必须完成的艰难的一步

[expr.const]的相关部分:

8.6常量表达式[表达式常量] […]表达式e是一个核心常量表达式,除非根据抽象机器6.8.1的规则,对e的求值将对以下表达式之一求值: […] 2.13-从cv void*类型转换为指向对象类型的指针


这与其说是一个答案,不如说是一个评论,因为我只是引用了上面写的内容,但我在这里写的内容与评论不符:

B.std::memmove和std::memcpy必须添加constexpr std::memmove和std::memcpy接受void*和const void*参数。这使得在纯C++中不可能实现为conExPR,因为常量表达式不能根据[Exp.const ]来评估从类型CV空隙*到指针类型到对象类型的转换。 然而,这些函数不仅很流行,而且在标准库中广泛使用,以获得更好的性能。不让它们成为constexpr将迫使标准库开发人员为它们提供编译器内部函数。这是必须完成的艰难的一步

[expr.const]的相关部分:

8.6常量表达式[表达式常量] […]表达式e是一个核心常量表达式,除非根据抽象机器6.8.1的规则,对e的求值将对以下表达式之一求值: […] 2.13-从cv void*类型转换为指向对象类型的指针


<>运行时代码中的C++对象模型通常被稍微松散地对待。它有相当严格的规则,但有一堆后门要么被允许,要么被宣布。后者意味着您仍然可以编写代码来执行它,但是C++对代码的行为没有任何保证。 在常量求值(constant evaluation,又名:代码的编译时执行)中,情况并非如此。对constexpr的限制是专门为了让对象模型成为您必须遵循的真实对象,而没有可行的后门。即使是它偶尔允许的,也明确要求格式错误并产生编译错误,而不是保持沉默

基本上在运行时,您可以将内存视为字节存储。在编译时,您不能;不允许你这么做。即使在C++20中添加了constexpr代码中的动态分配,您也不会玩很多通常会玩的游戏

memcpy处理字节的存储,来回复制它们而不知道是什么 他们不是说。bitcast同时知道源对象和目标对象,除非源对象和目标对象适合于bitcast,否则它将不允许您这样做,即:可复制性很低

如果您想让bitcast在编译时工作,它还可以对这两个对象的内容进行修改。特别是,不能对指针或包含任何类型指针的任何对象进行比特广播。或参考资料


这是因为编译时的指针不仅仅是地址。为了捕获UB,编译时指针必须知道它指向的对象的真实动态类型。因此,编译时不允许只转换地址的指针转换。

< P>运行时代码中的C++对象模型通常被稍微宽松地对待。它有相当严格的规则,但有一堆后门要么被允许,要么被宣布。后者意味着您仍然可以编写代码来执行它,但是C++对代码的行为没有任何保证。 在常量求值(constant evaluation,又名:代码的编译时执行)中,情况并非如此。对constexpr的限制是专门为了让对象模型成为您必须遵循的真实对象,而没有可行的后门。即使是它偶尔允许的,也明确要求格式错误并产生编译错误,而不是保持沉默

基本上在运行时,您可以将内存视为字节存储。在编译时,您不能;不允许你这么做。即使在C++20中添加了constexpr代码中的动态分配,您也不会玩很多通常会玩的游戏

memcpy处理字节的存储,来回复制它们而不知道它们的含义。bitcast同时知道源对象和目标对象,除非源对象和目标对象适合于bitcast,否则它将不允许您这样做,即:可复制性很低

如果您想让bitcast在编译时工作,它还可以对这两个对象的内容进行修改。特别是,不能对指针或包含任何类型指针的任何对象进行比特广播。或参考资料


这是因为编译时的指针不仅仅是地址。为了捕获UB,编译时指针必须知道它指向的对象的真实动态类型。因此,编译时不允许仅转换地址的指针转换。

谢谢您的回答,很抱歉没有活动。你能告诉我std::copy是constexpr吗?是否适用与bitcast相同的限制?既然每个迭代器都应该至少包含一个对容器的引用,那么它是如何工作的呢。@昆比:有什么需要解决的?不要将实现与行为混淆。复制复制对象;这就是它的行为。std::copy是constexpr;这也是它的行为。在该函数中发生什么来创建该行为与您无关,最终与函数的行为无关。好吧,很公平,我只是感兴趣,因为std::copy实际上看起来像一个类型化版本std::memcpy。但是,我想没有什么能阻止我去看一些实现。谢谢你的回答,很抱歉没有活动。你能告诉我std::copy是constexpr吗?是否适用与bitcast相同的限制?既然每个迭代器都应该至少包含一个对容器的引用,那么它是如何工作的呢。@昆比:有什么需要解决的?不要将实现与行为混淆。复制复制对象;这就是它的行为。std::copy是constexpr;这也是它的行为。在该函数中发生什么来创建该行为与您无关,最终与函数的行为无关。好吧,很公平,我只是感兴趣,因为std::copy实际上看起来像一个类型化版本std::memcpy。但我想没有什么能阻止我去研究一些实现。