C++11添加了constexpr关键字,可以添加到函数中以指定常量行为。C23以reproducible标签的形式添加了似乎相同的功能。这两种机制有何不同?
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函数添加权限。
[[reproducible]]
pure
strlen
constexpr
o75abkj42#
C11添加了constexpr关键字,可以添加到函数中以指定常量行为。C23以reproducible标签的形式添加了似乎相同的功能。这两种机制有何不同?一般来说,C(或C)constexpr说明符比C [[reproducible]]属性强得多,前者具有更广泛的语义和更强的约束。此外,constexpr是程序语义的一部分,而[[reproducible]]作为属性,作为编译器可以选择使用或不使用的可选元数据。[[reproducible]]可以自由地被删除,而不改变程序的有效性或语义,只要没有使用[[reproducible]]定义的函数不是从其作用域声明携带该属性的作用域中调用。仅考虑适用于这两种语言的方面,这里有一些更多的细节:
goto
reproducible
总的来说,constexpr和[[reproducible]]有一些一般的相似之处,但它们有非常不同的意义,效果和目的。它们离“完全相同”还差得远。另一方面,C23也将constexpr引入到C中,其对象的语义与C++ constexpr非常相似。然而,在C中,constexpr只能应用于对象,而不能应用于函数。
irtuqstp3#
有一些,但主要是constexpr旨在指函数调用的编译时评估(在适用的情况下)-而[[reproducible]]和[[unsequenced]]更多地作为对函数的限制,允许比其他法律的的更具侵入性的优化技术。在实践中,编译器可能会类似地处理这些方面的某些方面,但是constexpr在它允许的方面更加通用,并且更宽松,因为它可以降级到在运行时超出其限制。在这里看看openstd提案:https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2887.htm我们看到作者正在有效地标准化现有的GCC属性pure和const。这个问题attribute((const)) vs attribute((pure)) in GNU C有几个答案,可以更彻底地解释它们的行为和差异。
[[unsequenced]]
const
3条答案
按热度按时间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函数添加权限。o75abkj42#
C11添加了
constexpr
关键字,可以添加到函数中以指定常量行为。C23以reproducible标签的形式添加了似乎相同的功能。
这两种机制有何不同?
一般来说,C(或C)
constexpr
说明符比C[[reproducible]]
属性强得多,前者具有更广泛的语义和更强的约束。此外,constexpr
是程序语义的一部分,而[[reproducible]]
作为属性,作为编译器可以选择使用或不使用的可选元数据。[[reproducible]]
可以自由地被删除,而不改变程序的有效性或语义,只要没有使用[[reproducible]]
定义的函数不是从其作用域声明携带该属性的作用域中调用。仅考虑适用于这两种语言的方面,这里有一些更多的细节:
constexpr
函数的调用可以出现在常量表达式中,这意味着它们可以在编译时计算。前者不适用于可再现函数,并且在编译时不一定能够评估对可再现函数的调用。constexpr
函数对参数和返回类型有限制,而C可重现函数没有。constexpr
函数对可以出现在其定义中的语句类型有限制(goto
,标签,...),而C可再现函数则没有。constexpr
函数。在C中,用reproducible
属性定义的函数可以在任何转换单元中安全地重新声明,而不需要它。constexpr
函数不能写入非局部对象,也不能读取大多数非局部对象。一个C reproducible函数不限制它可以读取哪些对象。可再现函数可以经由作为参数提供给它的指针来写入非局部对象。constexpr
函数必须产生相同的返回值(如果有的话),而两次调用具有相同参数的可重复函数必须产生相同的返回值,只有当调用一个接一个地执行时。总的来说,
constexpr
和[[reproducible]]
有一些一般的相似之处,但它们有非常不同的意义,效果和目的。它们离“完全相同”还差得远。另一方面,C23也将constexpr
引入到C中,其对象的语义与C++constexpr
非常相似。然而,在C中,constexpr
只能应用于对象,而不能应用于函数。irtuqstp3#
有一些,但主要是
constexpr
旨在指函数调用的编译时评估(在适用的情况下)-而[[reproducible]]
和[[unsequenced]]
更多地作为对函数的限制,允许比其他法律的的更具侵入性的优化技术。在实践中,编译器可能会类似地处理这些方面的某些方面,但是
constexpr
在它允许的方面更加通用,并且更宽松,因为它可以降级到在运行时超出其限制。在这里看看openstd提案:https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2887.htm我们看到作者正在有效地标准化现有的GCC属性
pure
和const
。这个问题attribute((const)) vs attribute((pure)) in GNU C有几个答案,可以更彻底地解释它们的行为和差异。