Question

Possible Duplicate:
C++ Static member method call on class instance

Today I discovered that something I had long (and I mean long—like, for twenty years), thought illegal in C++ is actually legal. Namely, calling a static member function as if it belonged to an individual object. For example:

struct Foo
{
    static void bar() { cout << "Whatever."; }
};

void caller()
{
    Foo foo;
    foo.bar();    // Legal -- what?
}

I normally see static member functions being called strictly with "scope resolution syntax," thus:

Foo::bar();

This makes sense, because a static member function is not associated with any particular instance of the class, and therefore we wouldn't expect a particular instance to be syntactically "attached" to the function call.

Yet I discovered today that GCC 4.2, GCC 4.7.1, and Clang 3.1 (as a random sampling of compilers) accept the former syntax, as well as:

Foo* foo = new Foo;
foo->bar();

In my particular case, the legality of this expression led to a runtime error, which convinced me that the peculiarity of this syntax is of more than academic interest—it has practical consequences.

Why does C++ allow static member functions to be called as if they were direct members of individual objects—that is, by using the . or -> syntax attached to an object instance?

Was it helpful?

Solution

Presumably so you can call it in places where you may not know the class type of something but the compiler does.

Say I had a bunch of classes that each has a static member that returned the class name:

class Foo
{
    static const char* ClassName() { return "Foo"; }
};

class Bar
{
    static const char* ClassName() { return "Bar"; }
};

Then all over my code I could do things like:

Foo foo;

printf( "This is a %s\n", foo.ClassName() );    

Without having to worry about knowing the class of my objects all the time. This would be very convenient when writing templates for example.

OTHER TIPS

In The Design and Evolution of C++ at page 288, Bjarne Stroustrup mentions that in the days before static member functions, programmers used hacks like ((X*)0)->f() to call member functions that didn't need an object. My guess is that when static member functions were added to the language, access through -> was allowed so that programmers with code like that could change f to static without having to hunt down and change every use of it.

It's like this because the standard says that's how it works. n3290 § 9.4 states:

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) to refer to a static member. A static member may be referred to using the class member access syntax, in which case the object expression is evaluated. [ Example:

struct process { 
  static void reschedule(); 
}; 

process& g();

void f() { 
  process::reschedule(); // OK: no object necessary
  g().reschedule(); // g() is called 
} 

end example ]

From The Evolution of C++ (pdf), section 8. Static Member Functions:

...It was also observed that nonportable code, such as

    ((x*)0)->f();

was used to simulate static member functions.

So my guess is (based on the pattern of rationale for almost every other weird syntactical thing) they allowed invoking a static member function when you just had the type to provide backwards compatibility with an established but broken idiom.

If you don't subscribe to the "because the standard says so" school of causality, I also suggest that static methods are old enough to come from a time when people actually worried about the extra overhead from passing the this argument to a function call, so making pure functions "static" as an optimization was probably all the rage in 1985.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top