Bug 52902 - Pointer to member rejected in constant expression
Summary: Pointer to member rejected in constant expression
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.7.0
: P3 normal
Target Milestone: 5.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks: constexpr
  Show dependency treegraph
 
Reported: 2012-04-07 17:31 UTC by freunddeslichts
Modified: 2015-09-04 14:52 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2015-09-04 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
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.