在C++11的constexpr和C23的constexpr之间有什么区别?

y3bcpkx1  于 2023-08-03  发布在  其他
关注(0)|答案(3)|浏览(110)

C++11添加了constexpr关键字,可以添加到函数中以指定常量行为。
C23以reproducible标签的形式添加了似乎相同的功能。
这两种机制有何不同?

weylhg0b

weylhg0b1#

[[reproducible]]类似于GCC的pure
一个函数是pure,如果它除了返回值之外对程序的状态没有可观察到的影响,并且如果在相同程序状态的上下文中重复调用将返回相同的值。
典型的pure函数是strlen。它不会明显改变程序状态。如果整个程序状态保持不变,包括指针参数所指向的内存内容,它将返回相同的值。
[[reproducible]]要求函数是无效的和幂等的,这些术语在标准中有特定的含义。pure属性的文档很少,但其意图似乎是,当所有指针或数组类型都有const限定的目标类型时,它们会达成一致。
这与C++ constexpr不同,它装饰了一个可以在常量表达式中调用的函数,因此在翻译时以几种方式...
首先,[[reproducible]]是关于函数调用的Assert。相反,constexpr是一个Assert,表明在翻译时可能会有一些调用。
其次,constexpr不要求constexpr函数的常量表达式调用无效(至少从C14开始),或者在给定程序状态的情况下是幂等的(至少从C23开始)。Example.
在C11中(直到C14),constexpr * 接近无效和幂等。这是因为委员会有意为constexpr函数添加权限。

o75abkj4

o75abkj42#

C11添加了constexpr关键字,可以添加到函数中以指定常量行为。
C23以reproducible标签的形式添加了似乎相同的功能。
这两种机制有何不同?
一般来说,C
(或C)constexpr说明符比C [[reproducible]]属性强得多,前者具有更广泛的语义和更强的约束。此外,constexpr是程序语义的一部分,而[[reproducible]]作为属性,作为编译器可以选择使用或不使用的可选元数据。[[reproducible]]可以自由地被删除,而不改变程序的有效性或语义,只要没有使用[[reproducible]]定义的函数不是从其作用域声明携带该属性的作用域中调用。
仅考虑适用于这两种语言的方面,这里有一些更多的细节:

  • constexpr函数的调用可以出现在常量表达式中,这意味着它们可以在编译时计算。前者不适用于可再现函数,并且在编译时不一定能够评估对可再现函数的调用。
  • C++ constexpr函数对参数和返回类型有限制,而C可重现函数没有。
  • 在某些版本的C++中,constexpr函数对可以出现在其定义中的语句类型有限制(goto,标签,...),而C可再现函数则没有。
  • 在C++中,函数的定义和所有声明必须一致,以确定它是否是constexpr函数。在C中,用reproducible属性定义的函数可以在任何转换单元中安全地重新声明,而不需要它。
  • C++ constexpr函数不能写入非局部对象,也不能读取大多数非局部对象。一个C reproducible函数不限制它可以读取哪些对象。可再现函数可以经由作为参数提供给它的指针来写入非局部对象。
  • 每次调用具有相同参数的C++ constexpr函数必须产生相同的返回值(如果有的话),而两次调用具有相同参数的可重复函数必须产生相同的返回值,只有当调用一个接一个地执行时。

总的来说,constexpr[[reproducible]]有一些一般的相似之处,但它们有非常不同的意义,效果和目的。它们离“完全相同”还差得远。另一方面,C23也将constexpr引入到C中,其对象的语义与C++ constexpr非常相似。然而,在C中,constexpr只能应用于对象,而不能应用于函数。

irtuqstp

irtuqstp3#

有一些,但主要是constexpr旨在指函数调用的编译时评估(在适用的情况下)-而[[reproducible]][[unsequenced]]更多地作为对函数的限制,允许比其他法律的的更具侵入性的优化技术。
在实践中,编译器可能会类似地处理这些方面的某些方面,但是constexpr在它允许的方面更加通用,并且更宽松,因为它可以降级到在运行时超出其限制。
在这里看看openstd提案:https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2887.htm我们看到作者正在有效地标准化现有的GCC属性pureconst。这个问题attribute((const)) vs attribute((pure)) in GNU C有几个答案,可以更彻底地解释它们的行为和差异。

相关问题