Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

a question about the precedence of C++ operators "address of" and "scope resolution"

Tags:

Hello I have this code with a compiler error (error is from Microsoft Visual Studio 2008):

class B { protected:     int b; };  class A : public B { public:     void foo() { &B::b; }  // error C2248: 'B::b' : cannot access protected member declared in class 'B' }; 

while this code is error free:

class B { protected:     int b; };  class A : public B { public:     void foo() { &(B::b); } }; 

The two snippets seem to me equivalent based on my knowledge of the precedence of operators, because :: has an higher precedence than & (see for example table 2 at page 137 of "JOINT STRIKE FIGHTER AIR VEHICLE C++ CODING STANDARDS FOR THE SYSTEM DEVELOPMENT AND DEMONSTRATION PROGRAM" )

But they are different... I think it is something related to "pointer-to-data-member" but I do not know how does it fit with the operators precedence.

Any explanation?

like image 439
Alessandro Jacopson Avatar asked Feb 16 '11 15:02

Alessandro Jacopson


People also ask

Which operator has more precedence among the following?

Explanation: Operator ++ has the highest precedence than / , * and +.

Where in C the order of precedence of operators do not exist?

Where in C the order of precedence of operators do not exist? Explanation: None.

How does precedence and associativity play a role in evaluating an expression explain?

Two operator characteristics determine how operands group with operators: precedence and associativity. Precedence is the priority for grouping different types of operators with their operands. Associativity is the left-to-right or right-to-left order for grouping operands to operators that have the same precedence.

Which operator has highest precedence in C language?

Certain operators have higher precedence than others; for example, the multiplication operator has a higher precedence than the addition operator. For example, x = 7 + 3 * 2; here, x is assigned 13, not 20 because operator * has a higher precedence than +, so it first gets multiplied with 3*2 and then adds into 7.


1 Answers

In the first case you're taking the address of pointer-to-member B::b. Since such a pointer is NOT a member of the parent of A but a separate object, it can't access it via the protected mechanism.

In the SECOND case where it works you're asking for the address of the specific instance of b, qualifying it with its base class so that in the case of multiple inheritance the compiler would know which base class you mean. In this context the protected attribute is visible.

Note that this compiles:

class B { protected: int b; };  class A : public B { public: void foo(){ &A::b; }  // Note here &A:: instead of &B:: }; 

As an added example it doesn't work for the same reason that the following (hopefully more familiar) code doesn't work:

class B { protected: int b; };  class A : public B { public: void foo(const B* b_obj) { b_obj->b; } }; 
like image 154
Mark B Avatar answered Apr 28 '23 02:04

Mark B