Does a virtual function override a non-virtual function with the same name in the base class?

Does the following standard comply? Can you give a section?

struct A { virtual void func() = 0; }; struct B { void func(){} }; struct C : public A, public B { virtual void func(){ B::func(); } }; 

I get a strange compiler warning in VS2010 in equivalent, but more complex code, pointing to a func declaration in a derived class: warning C4505: unreferenced local function has been removed . I have no idea why the compiler thinks that the virtual function declared in the class is local; however, I cannot reproduce this warning in a simpler example.

Edit:

I figured out a small example for a warning alert. I think I went the wrong way, believing that this is due to the hide function. Here's the playback case:

 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; // } 

I am sure this is just a VS2010 error.

+6
source share
3 answers

The code is correctly generated. C::func overrides A::func . B::func is an unrelated function. The spectrum reads (10.3 / 2):

If the vf virtual member function is declared in the Base class and in the Derived class obtained directly or indirectly from Base , the vf member function with the same name, the parameter type is -list, cv-qualification and ref-qualifier (or the absence of the same ), like Base::vf , then Derived::vf also virtual (regardless of whether it is declared or not), and it overrides 111 Base::vf .

C::func has the same name as A::func , and A::func is virtual, so C::func overrides A::func . B::func not related to A::func ; I do not know that there is any language in the specification that directly addresses this script.

The Visual C ++ 11 Beta compiler does not generate any warnings or errors for this code.

+3
source

Usually, virtual functions cannot be eliminated by the linker as dead code, since their addresses should appear in the vtable. However, if the vtable for struct C was defined as dead code (which can happen if all the constructors are also dead code), then this last remaining link can also be removed.

Since the function is declared inline, this dead code removal optimization should not wait for link time; this can be done by the compiler. The Standard states (see Section 7.1.2):

The built-in function must be defined in each translation unit in which it is used , and must have exactly the same definition in each case (3.2). [Note: a call to a built-in function can be met before its definition appears in the translation block. - end note] If a function definition appears in the translation block before its first declaration as inline, the program is poorly formed. If a function with an external link is declared inline in one translation unit, it must be declared embedded in all translation units in which it appears; no diagnostics required. An inline function with external communication must have the same address in all translation units. The local static variable in the extern inline function always refers to the same object. The string literal in the body of the extern inline function is the same object in different translation units. [Note. The string literal contained in the default argument is not part of the built-in function just because the expression is used in the function call from this built-in function. - end note] The type defined inside the body of the extern inline function is the same type in each translation unit.

If the compiler can determine that a function is never used in this translation unit, he knows that any translation unit that uses this function must contain its own identical definition and will generate code. Thus, it can skip code generation just as if it had no external connection at all.

Generating a warning is completely pointless, as there will be a large number of false positives (when the inline function is used as odr and the code is generated in some other compilation unit).

+1
source

Let me do this for you.

function : removed local function without references

This function is local and is not specified in the module body; therefore, the function is dead code.

The compiler did not generate code for this dead function.

The compiler statically determined that the function is not used, so it does not generate code for this function and warns you that you have useless code. A little more than a normal unused variable warning, but about the same effect: dead code smells.

0
source

Source: https://habr.com/ru/post/915124/


All Articles