Calling static member function through object instance

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Joost Ronkes Agerbeek

    Calling static member function through object instance

    Why is it allowed in C++ to call a static member function of an object
    through an instance of that object? Is it just convenience?

    tia,
    Joost Ronkes Agerbeek


  • Janusz Szpilewski

    #2
    Re: Calling static member function through object instance

    Joost Ronkes Agerbeek wrote:[color=blue]
    > Why is it allowed in C++ to call a static member function of an object
    > through an instance of that object? Is it just convenience?
    >[/color]

    Static member functions primarily follow the invocation convention for
    member functions. However as they may be invoked without constructing
    any object the extra syntax (qualified id) is provided for this case.

    Regards,
    Janusz

    Comment

    • jeffc

      #3
      Re: Calling static member function through object instance


      "Joost Ronkes Agerbeek" <joost@ronkes.n l> wrote in message
      news:4005192f$0 $314$e4fe514c@n ews.xs4all.nl.. .[color=blue]
      > Why is it allowed in C++ to call a static member function of an object
      > through an instance of that object? Is it just convenience?[/color]

      I think the question might be answered if you asked a different question.
      If I were to ask you why it should NOT be allowed, what would you say?


      Comment

      • Joost Ronkes Agerbeek

        #4
        Re: Calling static member function through object instance

        > I think the question might be answered if you asked a different question.[color=blue]
        > If I were to ask you why it should NOT be allowed, what would you say?[/color]
        I would say that, were it not allowed, it would always be clear whether a
        call was to a static member or a non-static member.

        Part of what brought up this question for me was a passage in A Programmer's
        Introduction to C# by Eric Gunnerson regarding calls to static methods
        (p.66): "This is unlike the C++ behavior where a static member can be
        accessed either through the class name or the instance name. In C++, this
        leads to some readability problems, as it's sometimes not clear from the
        code whether an access is static or through an instance."

        By the way, I sent a reply to Janusz, but accidentely sent it to him in
        person instead of to the newsgroup. Here is my reply and his reply to that
        reply. (I removed the offending button in my newsreader ;-).)

        Thanks for your insights.

        Joost

        Joost Ronkes Agerbeek wrote:[color=blue]
        > Isn't it the other way around? Static member functions operate on the[/color]
        class,[color=blue]
        > not the object, so you have to write object::static_ function() but for
        > convenience you can also write instance.static _function(). I know C#[/color]
        doesn't[color=blue]
        > allow invoking a member function on an object instance: you have to use[/color]
        the[color=blue]
        > class so that it is always clear you are calling a static member function.
        > This triggered my original question: if there is an explicit reason the
        > designers of C# don't allow static member invocation through an instance,
        > then the designers of C++ must also have a reason why they do allow static
        > member invocation through an instance, but what is it?[/color]

        Hard to speak in the name of C++ designers, however in the C++ standard
        (9.4/2) one may find the following statement:

        "A static member s of class X may be referred to using the qualified-id
        expression X::s; it is not necessary to use the class member access
        syntax. (5.2.5)"

        5.2.5 says about . -> type access

        Some paragraphs before discuss class member access in general and from
        that perspective one may think of static members as a special case
        following the general concept as close as possible.
        AFAIK static member functions were not present in C++ from the beginning
        and were added somewhat later. So they were expected not to introduce
        too many changes.

        So I think it may be the reason of differences between C++ (and Java I
        think) and C#. The first attitude focuses on keeping language concepts
        consistent, fitting static member functions in the scope of member
        functions and the second keeps clean programming style in mind.

        Regards,
        Janusz







        Comment

        • jeffc

          #5
          Re: Calling static member function through object instance


          "Joost Ronkes Agerbeek" <joost@ronkes.n l> wrote in message
          news:40064abd$0 $333$e4fe514c@n ews.xs4all.nl.. .[color=blue][color=green]
          > > I think the question might be answered if you asked a different[/color][/color]
          question.[color=blue][color=green]
          > > If I were to ask you why it should NOT be allowed, what would you say?[/color][/color]
          [color=blue]
          > I would say that, were it not allowed, it would always be clear whether a
          > call was to a static member or a non-static member.
          >
          > Part of what brought up this question for me was a passage in A[/color]
          Programmer's[color=blue]
          > Introduction to C# by Eric Gunnerson regarding calls to static methods
          > (p.66): "This is unlike the C++ behavior where a static member can be
          > accessed either through the class name or the instance name. In C++, this
          > leads to some readability problems, as it's sometimes not clear from the
          > code whether an access is static or through an instance."[/color]

          Bjarne Stroustrup wrote a book about the design choices for the C++
          language - you might find a definitive answer there. I've thought for about
          5 seconds and don't have an idea about a case where that confusion might
          cause a problem, but there might well be one.


          Comment

          • E. Robert Tisdale

            #6
            Re: Calling static member function through object instance

            Joost Ronkes Agerbeek wrote:
            [color=blue]
            > Why is it allowed in C++ to call a static member function of an object
            > through an instance of that object? Is it just convenience?[/color]

            It is *not* allowed.
            [color=blue]
            > Is it just convenience?[/color]

            Comment

            • Robert Paul Clark

              #7
              Re: Calling static member function through object instance

              It is allowed. For convenience is probably the best answer.

              Example:
              #include <iostream>

              class A
              {
              public:
              static void foo() { std::cout << "foobar" << std::endl; };
              };

              int
              main()
              {
              A a;
              a.foo();
              }

              Output: foobar

              E. Robert Tisdale wrote:[color=blue]
              > Joost Ronkes Agerbeek wrote:
              >[color=green]
              >> Why is it allowed in C++ to call a static member function of an object
              >> through an instance of that object? Is it just convenience?[/color]
              >
              >
              > It is *not* allowed.
              >[color=green]
              >> Is it just convenience?[/color]
              >
              >[/color]

              Comment

              • Dario

                #8
                Re: Calling static member function through object instance

                Even the following code works!

                #include <cstdio>
                class A {
                public:
                static void foo() { printf("Hello world.\n"); };
                };
                int main() {
                A* a[10];
                int i;
                for(i=0; i<10; i++)
                a[i] = 0;
                a[5]->foo();
                a[50]->foo();
                }

                Comment

                • Karl Heinz Buchegger

                  #9
                  Re: Calling static member function through object instance

                  Dario wrote:[color=blue]
                  >
                  > Even the following code works![/color]

                  But *this* code is illegal.
                  [color=blue]
                  >
                  > #include <cstdio>
                  > class A {
                  > public:
                  > static void foo() { printf("Hello world.\n"); };
                  > };
                  > int main() {
                  > A* a[10];
                  > int i;
                  > for(i=0; i<10; i++)
                  > a[i] = 0;
                  > a[5]->foo();
                  > a[50]->foo();[/color]

                  you are dereferencing a 0-pointer.
                  And this is always a no-no, even if
                  your specific system does *not* crash.

                  --
                  Karl Heinz Buchegger
                  kbuchegg@gascad .at

                  Comment

                  • Dario

                    #10
                    Re: Calling static member function through object instance

                    Karl Heinz Buchegger wrote:[color=blue]
                    > Dario wrote:
                    >[color=green]
                    >> Even the following code works![/color]
                    >
                    >
                    > But *this* code is illegal.
                    >
                    >[color=green]
                    >> #include <cstdio>
                    >> class A {
                    >> public:
                    >> static void foo() { printf("Hello world.\n"); };
                    >> };
                    >> int main() {
                    >> A* a[10];
                    >> int i;
                    >> for(i=0; i<10; i++)
                    >> a[i] = 0;
                    >> a[5]->foo();
                    >> a[50]->foo();[/color]
                    >
                    >
                    > you are dereferencing a 0-pointer.
                    > And this is always a no-no, even if
                    > your specific system does *not* crash.[/color]

                    No !

                    When I evaluate
                    a[5]->foo()
                    a[5] is 0 but this does not matter
                    because foo is a static member;
                    a[50]->foo()
                    a[50] is whatever but this does not matter
                    because foo is a static member.

                    So my program is legal and works for every C++ compiler.

                    - Dario

                    Comment

                    • Karl Heinz Buchegger

                      #11
                      Re: Calling static member function through object instance

                      Dario wrote:[color=blue]
                      >[/color]
                      [color=blue][color=green]
                      > > you are dereferencing a 0-pointer.
                      > > And this is always a no-no, even if
                      > > your specific system does *not* crash.[/color]
                      >
                      > No ![/color]

                      Yes.
                      Read your code.
                      [color=blue]
                      >
                      > When I evaluate
                      > a[5]->foo()
                      > a[5] is 0 but this does not matter
                      > because foo is a static member;
                      > a[50]->foo()
                      > a[50] is whatever but this does not matter
                      > because foo is a static member.
                      >
                      > So my program is legal and works for every C++ compiler.[/color]

                      It is not legal, read the standard.
                      It doesn't matter if your compiler doesn't need
                      to dereference the pointer to call this function
                      under the hood. Your source code contains the
                      dereference and hence it is an illegal program.

                      --
                      Karl Heinz Buchegger
                      kbuchegg@gascad .at

                      Comment

                      • Jerry Coffin

                        #12
                        Re: Calling static member function through object instance

                        In article <bu8950$oid$1@g rillo.cs.interb usiness.it>,
                        dario@despammed .com says...

                        [ ... ]
                        [color=blue][color=green]
                        > > you are dereferencing a 0-pointer.
                        > > And this is always a no-no, even if
                        > > your specific system does *not* crash.[/color]
                        >
                        > No !
                        >
                        > When I evaluate
                        > a[5]->foo()
                        > a[5] is 0 but this does not matter
                        > because foo is a static member;[/color]

                        This is utterly irrelevant -- 5.2.5/1 says "the expression before the
                        dot or arrow is evaluated". Footnote 58 explicitly states that "This
                        evaluation happens even if the result is unnecessary to determine the
                        value of the entire postfix expression, for example if the id-expression
                        denotes a static member."

                        As such, you're assured that this dereferences a null pointer, which
                        gives undefined behavior.
                        [color=blue]
                        > So my program is legal and works for every C++ compiler.[/color]

                        Your program contains undefined behavior. If your definition of
                        "works" includes the possibility of crashing the computer, reformatting
                        the hard drive or making demons fly out of your nose, then you're right:
                        it works for every C++ compiler. Anybody who has a stricter definition
                        of work will want to avoid this construct.

                        --
                        Later,
                        Jerry.

                        The universe is a figment of its own imagination.

                        Comment

                        • Andy Buchanan

                          #13
                          Re: Calling static member function through object instance

                          On Thu, 15 Jan 2004 11:11:46 -0500, "jeffc" <nobody@nowhere .com>
                          wrote:[color=blue]
                          >"Joost Ronkes Agerbeek" <joost@ronkes.n l> wrote in message
                          >news:40064abd$ 0$333$e4fe514c@ news.xs4all.nl. ..[color=green][color=darkred]
                          >> > I think the question might be answered if you asked a different[/color][/color]
                          >question.[color=green][color=darkred]
                          >> > If I were to ask you why it should NOT be allowed, what would you say?[/color][/color]
                          >[color=green]
                          >> I would say that, were it not allowed, it would always be clear whether a
                          >> call was to a static member or a non-static member.
                          >>
                          >> Part of what brought up this question for me was a passage in A[/color]
                          >Programmer's[color=green]
                          >> Introduction to C# by Eric Gunnerson regarding calls to static methods
                          >> (p.66): "This is unlike the C++ behavior where a static member can be
                          >> accessed either through the class name or the instance name. In C++, this
                          >> leads to some readability problems, as it's sometimes not clear from the
                          >> code whether an access is static or through an instance."[/color]
                          >
                          >Bjarne Stroustrup wrote a book about the design choices for the C++
                          >language - you might find a definitive answer there. I've thought for about
                          >5 seconds and don't have an idea about a case where that confusion might
                          >cause a problem, but there might well be one.[/color]

                          It caught me out (shockingly recently), somehow I managed to miss the
                          whole call via instance mechanism for the 8+ years I've used c++, I
                          always used the :: form and I never saw anyone else do otherwise....

                          class BlahBlah
                          {
                          public:
                          BlahBlah& Instance(); // some sort of singleton i/f

                          private:
                          static void Eot( Client* client, int flags, void* uopt )
                          {
                          // Mistaken assumption: overload resolution calls
                          // the non-static member ( due to implicit 'this' )
                          // Actual behaviour: Recursive call & hang!
                          Instance().Eot( client, flags, uopt );
                          }
                          void Eot( Client* client, int flags, void* uopt );
                          };

                          In case you're wondering this was just code to interface
                          to a 3rd party C lib that used callbacks (yuk). Usually I would have
                          had different names for the two Eot() functions, but not this
                          time for some reason.

                          I would have thought the compiler might have determined
                          the Eot call to be amibiguous, but it didn't ( Compiler was a gcc
                          2.95.x derivitive.). Does a static member function rate higher
                          than an ordinary member function in overload resolution?

                          Comment

                          • Bjarne Stroustrup

                            #14
                            Re: Calling static member function through object instance

                            Andy Buchanan <news@globbits. co.uk> wrote in message news:<qusm00drg qgjip58kehcpp24 mvufdig6od@4ax. com>...[color=blue]
                            > On Thu, 15 Jan 2004 11:11:46 -0500, "jeffc" <nobody@nowhere .com>
                            > wrote:[color=green]
                            > >"Joost Ronkes Agerbeek" <joost@ronkes.n l> wrote in message
                            > >news:40064abd$ 0$333$e4fe514c@ news.xs4all.nl. ..[color=darkred]
                            > >> > I think the question might be answered if you asked a different[/color][/color]
                            > question.[color=green][color=darkred]
                            > >> > If I were to ask you why it should NOT be allowed, what would you say?[/color][/color]
                            >[color=green][color=darkred]
                            > >> I would say that, were it not allowed, it would always be clear whether a
                            > >> call was to a static member or a non-static member.
                            > >>
                            > >> Part of what brought up this question for me was a passage in A[/color][/color]
                            > Programmer's[color=green][color=darkred]
                            > >> Introduction to C# by Eric Gunnerson regarding calls to static methods
                            > >> (p.66): "This is unlike the C++ behavior where a static member can be
                            > >> accessed either through the class name or the instance name. In C++, this
                            > >> leads to some readability problems, as it's sometimes not clear from the
                            > >> code whether an access is static or through an instance."[/color]
                            > >
                            > >Bjarne Stroustrup wrote a book about the design choices for the C++
                            > >language - you might find a definitive answer there. I've thought for about
                            > >5 seconds and don't have an idea about a case where that confusion might
                            > >cause a problem, but there might well be one.[/color][/color]

                            The reason for allowing p->static_member_ function(); is exactly not to
                            require a user to remember if a function is static or not. Why should
                            the user care, except in the case where he/she wants to call without
                            an object?

                            [color=blue]
                            > It caught me out (shockingly recently), somehow I managed to miss the
                            > whole call via instance mechanism for the 8+ years I've used c++, I
                            > always used the :: form and I never saw anyone else do otherwise....
                            >
                            > class BlahBlah
                            > {
                            > public:
                            > BlahBlah& Instance(); // some sort of singleton i/f
                            >
                            > private:
                            > static void Eot( Client* client, int flags, void* uopt )
                            > {
                            > // Mistaken assumption: overload resolution calls
                            > // the non-static member ( due to implicit 'this' )
                            > // Actual behaviour: Recursive call & hang!
                            > Instance().Eot( client, flags, uopt );
                            > }
                            > void Eot( Client* client, int flags, void* uopt );
                            > };
                            >
                            > In case you're wondering this was just code to interface
                            > to a 3rd party C lib that used callbacks (yuk). Usually I would have
                            > had different names for the two Eot() functions, but not this
                            > time for some reason.
                            >
                            > I would have thought the compiler might have determined
                            > the Eot call to be amibiguous, but it didn't ( Compiler was a gcc
                            > 2.95.x derivitive.). Does a static member function rate higher
                            > than an ordinary member function in overload resolution?[/color]

                            No. That declaration is illegal. From the standard:

                            "[class.static.mf ct] 9.4.1 Static member functions

                            There shall not be a static and a nonstatic member function with the
                            same name
                            and the same parameter types (13.1)."

                            This has always been the rule. Without that rule, people could get
                            into all kinds of nasty problems.

                            It is always most anoying when a compiler fails to implement a clear
                            and simple language rule.

                            - Bjarne Stroustrup; http://www.research.att.com/~bs

                            Comment

                            • Old Wolf

                              #15
                              Re: Calling static member function through object instance

                              > > When I evaluate[color=blue][color=green]
                              > > a[5]->foo()
                              > > a[5] is 0 but this does not matter
                              > > because foo is a static member;[/color]
                              >
                              > This is utterly irrelevant -- 5.2.5/1 says "the expression before the
                              > dot or arrow is evaluated". Footnote 58 explicitly states that "This
                              > evaluation happens even if the result is unnecessary to determine the
                              > value of the entire postfix expression, for example if the id-expression
                              > denotes a static member."
                              >
                              > As such, you're assured that this dereferences a null pointer, which
                              > gives undefined behavior.[/color]

                              Your quote is irrelevant. "the expression before the dot or arrow"
                              is "a[5]". This is easy to evaluate: 0
                              You will have to look elsewhere in the Standard to find a definitive
                              answer.
                              Next question: what is the difference, if any, between:
                              a[5]->foo()
                              (*a[5]).foo()

                              Comment

                              Working...