Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ method call and type scope resolution ambiguity

I hope the title actually describes what I wanted to ask...

I wrote a piece of code that compiles with gcc and works as I intended. However, it does not compile with llvm and the code executes differently when compiled with icc!
Here is an example of the problem:

#include <iostream>

using std::cout; using std::endl;

class A {
public:
  virtual void foo() { cout << "A::foo()" << endl; }
};

class B : public A {
public:
  typedef A  base;
  virtual void foo() { cout << "B::foo()" << endl; }
};

int main() {
  typedef B  base;
  base* bp = new B();
  bp->base::foo(); 
}

gcc output: A::foo()
icc output: B::foo()

Could somebody explain what does the standard say about this case?

like image 292
Nowakus Avatar asked Jun 20 '12 08:06

Nowakus


People also ask

What is the scope resolution operator in C++?

In C++, scope resolution operator is ::. It is used for following purposes. 1) To access a global variable when there is a local variable with same name: 2) To define a function outside a class.

What is ambiguity resolution in inheritance in C++?

Define ambiguity resolution in inheritance. How can it be performed in C++? When a derived class has two base classes, base classes have function with the same name. If we want to call same name function of base class by child class then compiler get confused which function it should call.

What is the scope of a variable in C?

File Scope: These variables are usually declared outside of all of the functions and blocks, at the top of the program and can be accessed from any portion of the program. These are also called the global scope variables as they can be globally accessed. Note: To restrict access to the current file only, global variables can be marked as static.

How to get hidden names due to variable scopes?

The :: (scope resolution) operator is used to get hidden names due to variable scopes so that you can still use them. The scope resolution operator can be used as both unary and binary. You can use the unary scope operator if a namespace scope or global scope name is hidden by a particular declaration of an equivalent name during a block or class.


Video Answer


1 Answers

From C++11, §3.4.5/4:

If the id-expression in a class member access is a qualified-id of the form
    class-name-or-namespace-name::...
the class-name-or-namespace-name following the . or -> operator is first looked up in the class of the object expression and the name, if found, is used. Otherwise it is looked up in the context of the entire postfix-expression.

I don't think it can be clearer. This finds B::base, so the output should be A::foo().

like image 143
James Kanze Avatar answered Oct 26 '22 23:10

James Kanze