Why are class static functions not in the scope of the class?

Discussion in 'C++' started by Shriramana Sharma, May 3, 2013.

  1. Hello. Please see the following code:


    struct A { static int i ; } ;
    int A::* ip = & A::i ;


    I get the following errors with GCC 4.7.3 and Clang 3.2:

    GCC: error: cannot convert ‘int*’ to ‘int A::*’ in initialization

    Clang: error: cannot initialize a variable of type 'int A::*' with an rvalue of type 'int *'

    I thought members of a class are in its scope. Reading §9.4 (class.static) of C++11 doesn't help me any since it doesn't seem to speak about the scope of static members. Even §3.3 (basic.scope) and §3.3.7 (basic.scope.class) doesn't seem to help me.

    What am I missing? Please help. Thanks.
     
    Shriramana Sharma, May 3, 2013
    #1
    1. Advertising

  2. On 03.05.13 07.01, Shriramana Sharma wrote:
    > Hello. Please see the following code:
    >
    > struct A { static int i ; } ;
    > int A::* ip =& A::i ;


    First of all you are not talking about functions here. i is a class data
    member of A. However, this makes no important difference for the following.

    > I get the following errors with GCC 4.7.3 and Clang 3.2:
    >
    > GCC: error: cannot convert ‘int*’ to ‘int A::*’ in initialization
    >
    > Clang: error: cannot initialize a variable of type 'int A::*' with an rvalue of type 'int *'


    Static class members have different types than class instance members.
    This has technical reasons, but also a semantic difference.

    The type int A::* may point to any integer member within class A or it's
    base classes (if there are any). It will never point to any integer
    directly. It is a open instance reference to an integer inside A. I.e.
    with int A::* you can access a non-static integer in A using a *class
    instance* of type A (or a subclass of A).
    It is more like an array index, i.e. take the /4th/ integer in A, than
    like a pointer.

    If you want to dereference a int A::* you will /always/ need an object
    of type A (or subclass) because int A::* only tells /which/ integer of A
    to access but not of /which instance of A/.
    A a;
    a.*ip = 7;

    In theory one could define a semantic that also allows int A::* to point
    to a static member of A. But you would still need an instance of A to
    dereference the pointer, because you can't be sure that it refers only
    to a static int. C++ avoids things like this because it would only add
    more confusion. Furthermore there would be a significant runtime overhead.

    The type int* in contrast may point to any single integer outside a
    class or to any static integer in a class or also to any integer of a
    class *instance.*

    > I thought members of a class are in its scope.


    They are, but this only belongs to name resolution and access modifiers.
    It doesn't change the type of the objects.


    Marcel
     
    Marcel Müller, May 3, 2013
    #2
    1. Advertising

  3. On Friday, May 3, 2013 12:19:15 PM UTC+5:30, Paavo Helde wrote:
    > This is not about scope. The scope part (&A::i) was resolved just fine.
    > It is the assignment part which causes problems, as you want to assign
    > the result to a variable of a wrong type.
    >
    > Try
    > auto ip = & A::i ;
    > or
    > int* ip = & A::i ;


    Um thanks for your reply people. So IIUC int A::* is valid only within an Aobject, and the layout of A actually affects the contents of the pointer because you've called it an offset from the address location of the first byte of the object. So I should read int A::* as "a pointer within A to an integer" rather than "a point to an integer within A".

    Further to your feedback I also tried the following code which gave the following errors:

    struct A { int i ; static int si ; } ;
    int * ip = & A:: i ; // error: can't convert int A::* to int*
    int * sip = & A::si ;
    int A::* aip = & A:: i ;
    int A::* asip = & A::si ; // error: can't convert int* to int A::*

    and I understand it now, sort of...
     
    Shriramana Sharma, May 3, 2013
    #3
  4. On 03.05.13 11.49, Shriramana Sharma wrote:
    > struct A { int i ; static int si ; } ;
    > int * ip =& A:: i ; // error: can't convert int A::* to int*
    > int * sip =& A::si ;
    > int A::* aip =& A:: i ;
    > int A::* asip =& A::si ; // error: can't convert int* to int A::*


    Only for completion, there is a third valid variant:

    A a;
    int * ip2 =& a.i;

    In this case ip2 refer to i in exactly this single instance of A. As
    anyy other Pionter it gets invalid as soon as the object it refers to
    gets invalid.

    In Contrast the int A::* references never get invalid because they refer
    to a compile time Objekt, the Declaration of i within A. This is similar
    to function pointers. They always refer to compile time objects as well
    - as long as you don't write self modifying code, of course.


    Marcel
     
    Marcel Müller, May 3, 2013
    #4
  5. On Fri, 03 May 2013 02:49:55 -0700, Shriramana Sharma wrote:

    > Um thanks for your reply people. So IIUC int A::* is valid only within
    > an A object, and the layout of A actually affects the contents of the
    > pointer because you've called it an offset from the address location of
    > the first byte of the object. So I should read int A::* as "a pointer
    > within A to an integer" rather than "a point to an integer within A".


    That is right. The type 'A::*' is called a pointer-to-member (of A), but
    it would be more correct to call it a pointer-to-non-static-member (of A).

    Bart v Ingen Schenau
     
    Bart van Ingen Schenau, May 5, 2013
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Paul Opal
    Replies:
    12
    Views:
    962
    Paul Opal
    Oct 11, 2004
  2. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    913
    Mark Rae
    Dec 21, 2006
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,008
    Smokey Grindel
    Dec 2, 2006
  4. Robin
    Replies:
    0
    Views:
    420
    Robin
    Jun 6, 2007
  5. Hicham Mouline
    Replies:
    5
    Views:
    2,381
    James Kanze
    Dec 19, 2008
Loading...

Share This Page