鉴于我想改进我的C代码库。第一步是将函数标记为constexpr
,以满足所使用的C标准的要求。是否有方法确定函数是否可以标记为constexpr
?
我想到的唯一方法是将constexpr
添加到单个示例中,运行编译器,并检查它是否抱怨它不是constexpr
。重复直到检查完所有示例。这种方法无法扩展。
标签:Should we use constexpr everywhere we can?
鉴于我想改进我的C代码库。第一步是将函数标记为constexpr
,以满足所使用的C标准的要求。是否有方法确定函数是否可以标记为constexpr
?
我想到的唯一方法是将constexpr
添加到单个示例中,运行编译器,并检查它是否抱怨它不是constexpr
。重复直到检查完所有示例。这种方法无法扩展。
标签:Should we use constexpr everywhere we can?
2条答案
按热度按时间fhity93d1#
在C++23中,constexpr函数有两个要求:
如果你的代码库中的每个函数都满足这一点,我不会感到惊讶。
所以你可以标记每个模板化的内联函数
constexpr
。因为constexpr
函数是隐式的inline
,所以你不能对extern
函数这样做。这意味着头文件中的每个函数定义都可以是
constexpr
。(If你有constexpr函数的编译器错误,它永远不会产生常量表达式,升级你的编译器)
uxhixvfz2#
随着
constexpr
的放松越来越多,更容易问:有没有一种方法可以检测到 * 不应该 * 是
constexpr
的函数?以下函数不应该是
constexpr
:constexpr
,但如果没有定义,它们在常量表达式中将不可用constexpr
构造函数的类的成员函数constexpr
,但这个constexpr
会产生误导throw
,goto
等)constexpr
,参见P2448: Relaxing some constexpr restrictions所有其他函数(在某些代码库中构成了绝大多数函数)都可以是
constexpr
。您甚至可以使用类似clang-tidy规则的东西来自动执行此过程。C++20注意事项
它在C++20和更老的标准中更复杂,因为有以下规则:
对于既不是默认值也不是模板的constexpr函数或constexpr构造函数,如果不存在参数值,使得函数或构造函数的调用可能是核心常量表达式的求值子表达式,或者对于构造函数,是某些常量初始化对象的初始化全表达式的求值子表达式,则程序格式不正确,不需要诊断。
这个规则在前面提到的建议中被删除了,但是在C20中,它使得决定何时应用
constexpr
变得更加困难。自动证明是否存在一组参数来产生常量表达式并不容易。