以下标准是否符合要求?你能举出这个部分吗?
struct A
{
virtual void func() = 0;
};
struct B
{
void func(){}
};
struct C : public A, public B
{
virtual void func(){ B::func(); }
};
我在VS2010中收到了一个奇怪的编译器警告,它在相同但更复杂的代码中指向派生最多类中的func
声明:warning C4505: unreferenced local function has been removed
。我不知道为什么编译器认为在类中声明的虚函数是本地的;但是我不能在一个更简单的例子中重复这个警告。
我想出了一个警告的小责备案例。假设它与函数隐藏有关,我认为我走错了路。这是repro案例:
template<typename T>
struct C
{
int GetType() const;
virtual int func() const; // {return 4;} // Doing this inline removes the warning <--------------
};
template<typename T>
int C<T>::GetType() const
{
return 0;
}
template<>
int C<int>::GetType() const
{
return 12;
}
template<typename T>
int C<T>::func() const
{
return 3;
}
// Adding the following removes the warning <--------------------
// template<>
// int C<int>::func() const
// {
// return 4;
// }
我很确定这只是一个VS2010错误。
答案 0 :(得分:3)
代码格式正确。 C::func
会覆盖A::func
。 B::func
是一个无关的功能。规范如下(10.3 / 2):
如果在类
vf
和类Base
中声明虚拟成员函数Derived
,直接或间接地从Base
派生,则成员函数{{1声明同名,参数类型列表,cv-qualification和ref-qualifier(或缺少相同),vf
也是虚拟的(无论是否为如此声明)并且它覆盖了111Base::vf
。
Derived::vf
与Base::vf
同名,C::func
为虚拟,因此A::func
会覆盖A::func
。 C::func
与A::func
无关;我不知道规范中有任何语言明确地解决了这种情况。
Visual C ++ 11 Beta编译器不会为此代码发出任何警告或错误。
答案 1 :(得分:1)
通常,链接器不能将虚函数作为死代码消除,因为它们的地址必须出现在vtable中。但是,如果struct C
的vtable被确定为死代码(如果所有构造函数都是死代码,则可能会发生这种情况),那么也可以消除最后剩余的引用。
因为函数声明为inline
,所以这个死代码删除优化不必等到链接时间;它可以由编译器完成。标准说(参见第7.1.2节):
内联函数应在每个使用它的翻译单元中定义,并且在每种情况下都应具有完全相同的定义(3.2)。 [注意:在定义出现在翻译单元之前,可能会遇到对内联函数的调用。 - 结束注释]如果函数的定义在第一次声明为内联之前出现在翻译单元中,则程序格式不正确。如果是具有外部链接的功能 在一个翻译单元中内联声明,应在其出现的所有翻译单元中内联声明;无需诊断。具有外部链接的
inline
函数在所有翻译单元中应具有相同的地址。static
函数中的extern inline
局部变量始终引用同一对象。extern inline
函数体中的字符串文字是不同翻译单元中的同一对象。 [注意:出现在默认参数中的字符串文字不在内联函数的主体中,因为该表达式用于来自该内联函数的函数调用中。 - 结尾注释]extern inline
函数体内定义的类型在每个翻译单元中都是相同的类型。
如果编译器可以确定该函数从未在此转换单元中使用,则它知道任何使用该函数的转换单元必须包含其自己的相同定义,并将生成代码。因此它可以跳过代码生成,就像它根本没有外部链接一样。
然而,生成警告是完全没有意义的,因为会有大量的误报(当inline
函数被使用并且在其他编译单元中生成代码时)。
答案 2 :(得分:0)
function
:已删除未引用的本地功能给定的函数是本地的,在模块的主体中没有引用;因此,该功能是死代码。
编译器没有为这个死函数生成代码。
编译器静态地确定该函数未被使用,因此它不会为该函数生成代码并警告您有无用的代码。比通常的未使用的变量警告更复杂,但效果相同:死代码闻起来。