Bug 52902

Summary: Pointer to member rejected in constant expression
Product: gcc Reporter: freunddeslichts
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: daniel.kruegler
Priority: P3    
Version: 4.7.0   
Target Milestone: 5.0   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2015-09-04 00:00:00
Bug Depends on:    
Bug Blocks: 55004    

Description freunddeslichts 2012-04-07 17:31:14 UTC
#########################################################################


struct X {
  int a;
};

constexpr int X::* mem = &X::a;

void foo() 
{
  constexpr X x = {1};
  constexpr int k = x.a;          // ok

  constexpr int l = x.*mem;       // should be ok       <------------------

  //constexpr int const* m = &(x.a);  // legitimate error
}


#########################################################################

g++-4.7 -std=c++0x bug.cpp -o g47.out
bug.cpp: In function ‘void foo()’:
bug.cpp:29:24: error: ‘(const int*)(& x)’ is not a constant expression

#########################################################################


As far as I can see, a pointer to member access should be a constant expresssion, iff both the object and the pointer are constant expressions. 
This behaviour is shown by the clang++ compiler, which does not emit the above error.


It seems gcc evalutates the expression 

         x.*mem

as something like

         *((const int*)(& x) + mem)

In this implementation, the left (intermediate) operand to the + operator is not a constant expression, that's why gcc rejects it by mistake.
Comment 1 Markus Trippelsdorf 2015-09-04 14:07:50 UTC
*** Bug 67376 has been marked as a duplicate of this bug. ***
Comment 2 Markus Trippelsdorf 2015-09-04 14:28:21 UTC
Works with gcc-5 and trunk. Closing.