pointer member constant expression

Perry Smith pedz@easesoftware.net
Mon Feb 27 15:31:00 GMT 2006


Thank you and apologies to all.

I simply never looked at paragraph 1 of 5.19.  I just (for some  
reason) jumped over it.  But it says (as you state) that there is a  
difference between.  I discovered this yesterday but didn't want to  
add more noise to the mailing list.

Again -- thanks and sorry...
Perry


On Feb 27, 2006, at 6:00 AM, Dave Korn wrote:

> On 24 February 2006 23:42, Perry Smith wrote:
>
>> On Feb 24, 2006, at 8:55 AM, Richard Guenther wrote:
>
>>>> The problem is this:
>>>>
>>>> struct foo {
>>>>      int a;
>>>>      int b;
>>>>      int c;
>>>> };
>>>>
>>>> static const int foo::*j = &foo::c;                     // accepted
>>>>
>>>> class dog {
>>>>      static const int foo::*k = &foo::c;        // error };
>
>   It has been illegal to initialise a static class member inside  
> the class
> definition since sometime back in the early 90s.  You must provide  
> a static
> instantiation elsewhere and initialise that.
>
>>>> 5.19 (constant expressions) paragraph 2, the last item in the  
>>>> 1998 C+
>>>> + spec says " -- a pointer to member constant expression."  That
>>>> appears to be defined as: '&' qualified-id (5.19 paragraph 6).
>
>   Yes, the expression is a valid initialiser for the object, but the
> initialiser is in a place where it is not allowed.  BTW, please  
> remember here
> that you have identified the expression as being a pointer-to- 
> member constant
> expression, because later on you forget this fact and that's where  
> your
> confusion arises...
>
>> But '&' can occur in a constant-expression and 'foo::c' is a  
>> unique-id
>> which can also appear in a constant expression (see 5.19).  And as
>> far as the static const data member, 9.4.2 paragraph 4 says:
>
>   This clause does not apply to /all/ static const data members...
>
>>
>> If a static data member is of const integral or const enumeration
>> type,
>
>   ...only ones of integral or enumeral type.  And k, the static  
> data member in
> question, is a constant pointer-to-int-member-of-foo.
>
>> its declaration in the class definition can specify a
>> constant-initializer which shall be an integral constant expression
>> (5.19). In that case, the member can appear in integral constant
>> expressions within its scope. The member shall still be defined in
>> a namespace scope if it is used in the program and the namespace
>> scope definition shall not con- tain an initializer.
>>
>> Note that 5.19 states that '&foo::c' is an integral constant
>> expression.
>
>   It is no such thing, and 5.19 says no such thing, and this is the  
> point at
> which you've forgotten that you already identified it as being a
> pointer-to-member constant expression as defined under the terms of  
> 5.19.6.  A
> pointer-to-member is not any kind of integer.  5.19.2 states that  
> it can be
> considered as a /constant/ expression, "only for the purpose of non- 
> local
> static object initialization".  It does not say it can be considered a
> /constant integral/ expression.
>
>   And even if the initialiser expression was a constant integral  
> expression,
> and we were allowed to assign it to the member, that wouldn't  
> change the type
> of the member variable itself.  The type of that variable is as you  
> defined it
> in the class definition: it is "const int (foo::*)", and it's the  
> type of the
> member variable that 9.4.2 is talking about when it says whether  
> you can or
> can't initialise it in the class definition, not the type of the  
> value with
> which you initialise it - closely related though those two things  
> generally
> are, they are nonetheless distinct concepts.
>
>>  So I draw the conclusion that k is a const integral
>> type (but I have not seen a place in the spec that actually says
>> that a pointer to member is an integral expression but what else
>> could it be?
>
>   It is a unique type of it's own, called pointer-to-member.  This  
> is a
> compound type, fundamentally different to integral types (and  
> indeed to
> non-member-pointer types.)
>
>   Ah.  A thought has just occurred to me.  You may have the  
> misunderstanding
> that the static class member variable 'foo::k' is const.  It isn't;  
> the int to
> which it points is const.  You can assign it to point to any other
> int-member-of-foo at any time you like (and because it points to const
> I-M-O-F, it's ok to assign it to point at a non-const I-M-O-F but  
> you won't be
> allowed to modify that int through it).
>
>   Is a mixup between "const int foo::*" and "int foo::* const"  
> perhaps the
> root cause of your confusion?  If I read the standard correctly it  
> should be
> ok to initialise one of the latter in the class definition in the  
> way you are
> expecting for foo::k in your example.
>
>     cheers,
>       DaveK
> -- 
> Can't think of a witty .sigline today....
>
>



More information about the Gcc mailing list