用R Sahu的方法测试一下,gcc、clang、icc的答案好像是yes,这个指针调整会发生,除非基类是primary基类或者空基类。
测试代码:
#include <iostream>
namespace {
struct Base1
{
void b1()
{
std::cout << "b1() " << (void*)this << std::endl;
}
int x;
};
struct Base2
{
void b2()
{
std::cout << "b2() " << (void*)this << std::endl;
}
int x;
};
struct EmptyBase
{
void eb()
{
std::cout << "eb(): " << (void*)this << std::endl;
}
};
struct Derived : private Base1, Base2, EmptyBase
{
void derived()
{
b1();
b2();
eb();
std::cout << "derived(): " << (void*)this << std::endl;
}
};
}
int main()
{
Derived d;
d.derived();
}
匿名命名空间用于为基类提供内部链接。智能编译器可以确定基类的唯一用途是在这个翻译单元中,并且这种指针调整是不必要的。私有继承用于很好的衡量,但我认为它没有真正的意义。
示例 g++ 4.9.2 输出:
b1() 0x7fff5c5337d0
b2() 0x7fff5c5337d4
eb(): 0x7fff5c5337d0
derived(): 0x7fff5c5337d0
示例 clang 3.5.0 输出
b1() 0x7fff43fc07e0
b2() 0x7fff43fc07e4
eb(): 0x7fff43fc07e0
derived(): 0x7fff43fc07e0
示例 icc 15.0.0.077 输出:
b1() 0x7fff513e76d8
b2() 0x7fff513e76dc
eb(): 0x7fff513e76d8
derived(): 0x7fff513e76d8
所有三个编译器都将 this 指针调整为b2()
. 如果他们在这种简单的情况下不忽略此指针调整,那么他们很可能永远不会忽略此指针调整。主基类和空基类是例外。
据我所知,符合智能标准的编译器可以省略 this 指针调整,b2()
但这只是他们不做的优化。