为啥 g++ 不关注虚函数的 __attribute__((pure)) ?

Posted

技术标签:

【中文标题】为啥 g++ 不关注虚函数的 __attribute__((pure)) ?【英文标题】:Why doesn't g++ pay attention to __attribute__((pure)) for virtual functions?为什么 g++ 不关注虚函数的 __attribute__((pure)) ? 【发布时间】:2010-06-18 12:39:49 【问题描述】:

根据the GCC documentation,__attribute__((pure)) 告诉编译器一个函数没有副作用,因此可以进行公共子表达式消除。

此属性似乎适用于非虚拟功能,但不适用于虚拟功能。例如,考虑以下代码:

extern void f( int );

class C 
 public:
   int a1();
   int a2() __attribute__((pure));
   virtual int b1();
   virtual int b2() __attribute__((pure));
;

void test_a1( C *c ) 
   if( c->a1() ) 
      f( c->a1() );
   


void test_a2( C *c ) 
   if( c->a2() ) 
      f( c->a2() );
   


void test_b1( C *c ) 
   if( c->b1() ) 
      f( c->b1() );
   


void test_b2( C *c ) 
   if( c->b2() ) 
      f( c->b2() );
   

在启用优化(-O2 或 -Os)的情况下编译时,test_a2() 只调用一次C::a2(),但test_b2() 调用两次b2()

这是有原因的吗?是不是因为,即使C 类中的实现是纯的,g++ 也不能假设每个子类中的实现也是纯的?如果是这样,有没有办法告诉g++这个虚函数和每个子类的实现都是纯的?

【问题讨论】:

我注意到 __attribute__((nothrow)) 的行为方式也相同。 【参考方案1】:

如果不研究 g++ 的内部结构,我怀疑这是因为 g++ 不能假设每个子类的实现都是纯的(就像你说的那样)。

你能把b2 变成一个围绕虚拟非纯方法的非虚拟纯包装器吗?

【讨论】:

谢谢,这是一个有趣的想法。

以上是关于为啥 g++ 不关注虚函数的 __attribute__((pure)) ?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 g++ 不在这里执行结构打包?

__attribute__((weak)):弱引用,可以不实现

iOS 编译器__Attribute__的入门指南

__attribute__((weak)) zz

这个Mathematica三维图为啥画不出来

利用__attribute__((section("name")))构建初始化函数表