GCC 12建议为自定义vector的size()添加pure属性的技术疑问
GCC 12对
my_vector::size()建议添加__attribute__((pure))的疑问解答 首先看你的my_vector代码片段:
class my_vector { ... constexpr auto size() const noexcept -> size_type { assert(stride_ != 0); return nelems_/stride_; } };
切换到GCC 12后收到的编译错误提示:
error: function might be candidate for attribute 'pure' if it is known to return normally [-Werror=suggest-attribute=pure]
下面针对你的三个疑问逐一解答:
1. 该函数是否真的符合pure属性的要求?
GCC的__attribute__((pure))对函数的核心要求是:
- 不修改任何全局状态或函数参数(包括
this指向的对象,而你的函数是const成员函数,承诺不修改对象内部状态) - 返回值仅依赖于函数的输入(这里就是
this指向对象的nelems_和stride_成员) - 无额外副作用(除了读取输入之外的行为)
你的size()函数完全符合这些要求——只要assert在编译时可被消除(比如NDEBUG定义时),就算调试模式下的assert,GCC也会将其视为调试专属行为,不影响pure属性的判定。
至于你担心的多线程修改问题:pure属性是针对单线程语义下的函数行为给出的优化提示。如果其他线程并发修改this指向的对象,本身就违反了const成员函数的使用约定(const对象应保证不可变,或修改时需同步),这属于调用方的责任,不影响函数本身是否符合pure的判定。
2. 遵循编译器的这一建议是否通常是安全的?
只要你的函数确实符合pure的要求,添加这个属性通常是安全的:
- 确认
size()没有隐藏副作用(比如没有修改mutable成员,调试模式的assert不属于生产环境的副作用) - 确认
const成员函数的实现严格遵守了不修改对象状态的承诺
添加属性后,编译器可以进行更多优化,比如重复调用size()时只计算一次,减少不必要的计算开销。
3. 编译器能判断函数是pure的,为何不直接优化反而建议添加非标准扩展?
主要有三个原因:
- 编译器的分析是保守的:编译器能通过静态分析判断当前版本的函数符合
pure特征,但它无法预知你未来是否会修改函数、添加副作用。添加属性是你明确告诉编译器“这个函数始终满足pure要求”,避免编译器因保守分析错过优化机会。 - 标准C++无对应属性:C++标准里没有专门定义
pure这类属性,__attribute__((pure))是GCC的扩展,用来填补标准在优化提示上的空白,让开发者能主动给编译器传递明确的优化意图。 - 调试与生产模式的差异:比如你的函数里有
assert,调试模式下会有终止程序的副作用,但生产模式下没有。编译器无法确定你是否希望在所有模式下都按pure函数处理,需要你通过属性明确声明。
内容的提问来源于stack exchange,提问作者alfC
相关产品推荐
相关产品推荐

