Member function with static linkage - c++

I'm trying to understand why the following is an error:
class Foobar {
public:
static void do_something();
};
static void Foobar::do_something() {} // Error!
int main() {
Foobar::do_something();
}
This errors with "error: cannot declare member function 'static void Foobar::do_something()' to have static linkage" in g++, and "error: 'static' can only be specified inside the class definition" in clang++.
I understand that the way to fix this is to remove "static" in the definition of do_something on line 6. I don't, however, understand why this is an issue. Is it a mundane reason, such as "the C++ grammar dictates so", or is something more complicated going on?

The keyword static has several different meanings in C++, and the code you've written above uses them in two different ways.
In the context of member functions, static means "this member function does not have a receiver object. It's basically a normal function that's nested inside of the scope of the class."
In the context of function declarations, static means "this function is scoped only to this file and can't be called from other places."
When you implemented the function by writing
static void Foobar::do_something() {} // Error!
the compiler interpreted the static here to mean "I'm implementing this member function, and I want to make that function local just to this file." That's not allowed in C++ because it causes some confusion: if multiple different files all defined their own implementation of a member function and then declared them static to avoid collisions at linking, calling the same member function from different places would result in different behavior!
Fortunately, as you noted, there's an easy fix: just delete the static keyword from the definition:
void Foobar::do_something() {} // Should be good to go!
This is perfectly fine because the compiler already knows that do_something is a static member function, since you told it about that earlier on.

This question is already well answered. Details for static can be read here
Golden Rule:
The static keyword is only used with the declaration of a static member, inside the class definition, but not with the definition of that static member.

For future reference, to have the static method put the static method code above where it is called in the same file and define it as static. Also remove the class reference.
So instead of:
static void Foobar::do_something() {} // Error!
Use:
static void doSomething(){} // the Foobar is removed
It won't be able to access object values but just pass these in as parameters.

Related

Why is it not allowed to put the `static` keyword for class member definitions in namespace scope?

struct A
{
static void f();
};
static void A::f() {} //illegal
Why's this not allowed? Am asking this because the rule seems inconsistent with other keywords.
You must put constexpr on both.
You can put inline on both, but you can also omit one of them. This is useful that you can omit inline in class definition, which is not important information of the interface.
But the rules for static on class members doesn't really make sense. Shouldn't it be consistent with constexpr?
I know static means internal linkage for namespace-scope functions, and this partly explains the current shape. But isn't distinguishing between free functions and class member functions having no ambiguity in namespace scope? For example, if you write static void A::f() {} it's unambiguous that you're defining a member function of A, if A is a class name.
The static in class have other meaning the static in a global or namespace.
when you declared symbol as static in the class, you don't want it to be a global static.
1. static member
In the class it is mean the symbol is class related not object related, means for member variable, there is only one instance for all the objects, and for function, it doesn't have access to non static members, which are object oriented. .
2. static global
In global scope, the static indicate the object or function is local only, and can't be exported (like using extern) to other files. in addition it let you use same name in other file for other variable. so if it located in header file, any file including the header, will have different instance of the symbol.
Therefore if you were allowed to use it in the global scope for a member, then there was an ambiguity.

Using static function in class where a variable depends on constructor

Lets say I have a class with a static function. This function is called as static by another part of the code, without instantiating a class object. However, this static function also has in its code a dependance on variable x. x, however, is only initialized to a certain value or cleared in the constructor. But, given that no object of the class is instantiated, I believe that the variable is undefined. So, I have a few questions:
1) Is the constructor called at all?
2) Is the variable x undefined?
How can I work around a case like that?
In the example below, i'd want y to be 25, but can it ever be?
class CExample
{
public:
CExample(void);
~CExample(void);
static void foo();
int x;
};
CExample::CExample()
{
x = 5;
}
void CExample::foo()
{
int y = x*5;
}
Your code doesn't compile since the static function is using a variable which will only exist in objects instantiated by the class.
I'm not sure you've understood static. Only one static function exist. You can call it from anywhere. Which instance if CExample's x is it supposed to use?
This looks like a case of bad design. You could fix it so that it compiles by making x static and initialising it with 5. However you are probably a lot of better rethinking your design and what you want it to do. Remember there is only ever one instance of something that is static but there are as many instances of CExample as times you call it's constructor.
A static member function is a service of the class, not of a specific object of the class. A class's static data members and static member functions exist independently of instantiation of a object of that class.
The use of a static function will not call the constructor of its respective class, therefore your variable will not exist, causing a compilation error.
Just remember static member functions exist and operate independently of any objects of the class.
It's illegal to access a non-static member from a static function. See the output of gcc when I try to compile your program:
test.cpp: In static member function ‘static void CExample::foo()’:
test.cpp:9: error: invalid use of member ‘CExample::x’ in static member function

Why is calling a static member function with . or -> syntax legal? [duplicate]

This question already has answers here:
Closed 10 years ago.
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?
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.
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.
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.

How many instances are there of static data declared inside a static member function in a header file?

I'm working on compiling Cppcheck on AIX using xlC. Every checker class is derived from a Check class, whose constructor is responsible for registering that type of checker in a global static list.
Here's the relevant part of the code in question (filenames link to full source on Github):
check.h
class Check {
public:
Check() {
instances().push_back(this);
instances().sort();
}
static std::list<Check *> &instances() {
static std::list<Check *> _instances;
return _instances;
}
// ...
};
checkbufferoverrun.h
class CheckBufferOverrun: public Check {
// ...
};
checkbufferoverrun.cpp
// Register this check class (by creating a static instance of it)
namespace
{
CheckBufferOverrun instance;
}
Notice how the _instances static variable is declared inside a static function in the header file (there is no corresponding check.cpp file). When compiled with g++, the compiler and linker work together to ensure that there is only one implementation of the static instances() function, and therefore only one instance of the static _instances list. All the different checker classes instantiated in different .cpp files get registered in the same _instances list together.
However, under AIX's xlC, this same code ends up creating a different instances() function for every .cpp file in which it is included, which each having a different static _instances list. So there is no longer a single central _instances list, which causes Cppcheck to not run most of its checks.
Which compiler's behaviour is correct in this case?
Update: This question is not about how to fix the problem, I've already done that. I'm curious about which behaviour is correct.
g++ has the correct behavior: there should be exactly one instance of the object. The C++ Standard says (C++03 7.1.2/4):
A static local variable in an extern inline function always refers to the same object.
Because the class has external linkage, the static member function also has external linkage, per C++03 3.5/5:
a member function...has external linkage if the name of the class has external linkage.
Because the member function is defined in the class definition, it is an inline function, per C++03 7.1.2/3:
A function defined within a class definition is an inline function.
In this particular case g++ is correct (assuming that the instances() static member function returns a reference, that is a typo, right?). You might want to move the definition of the instances() function to a cpp file, that should be a work around in xlc.
Correct it to:
static std::list<Check *>& instances();
// check.cpp
std::list<Check *> & Check::instances()
{
static std::list<Check *> _instances;
return _instances;
}
If you inline the function in the header file, each compilation unit will initially compile its own definition. However at link-time they should be reduced to one instance because of the One-Definition Rule.
I am sure you are aware, of course, that your constructor to Check is not thread-safe. Your singleton constructor is also not totally thread-safe because although the ODR ensures the threads between them can only create one instance, the constructor of list is not atomic and therefore I am not sure it is guaranteed to be completely constructed before the other thread sees it.
For a totally thread-safe way of constructing singletons or non-atomic statics, you can use boost::once.

Questions about the static keyword with functions and data

I have a few questions about the static keyword in C++ (and probably with other languages as well.) What is the purpose of declaring a function as static?
void static foo(int aNumber) {
... }
How about a static inline function?
void static inline foo(int aNumber) {
... }
Is there any benefit to using the static keyword with a function, and do those benefits apply to class functions as well?
I realize some datatypes like structs and arrays have to be static when compiling with an older compiler, but is there any point when using a new ANSI-C++ compiler (like MS VC++ 2008)? I know that using a static variable inside a loop saves time by keeping the data in memory and not reallocating memory every loop iteration, but how about when a variable is declared only once, like at the top of a header file or within a namespace?
Depends on Context:
Like many things in C++, static means different things depending on its context.
It's very common in C++ for the same word to mean different things depending on its context.
For example:
* is used for multiplication, dereferencing a pointer, and creating pointers.
& is used to get the address of variables, to declare a reference, and as a bitwise AND operator.
Global use of static:
If you declare a function or variable as static outside of a class and in global scope, it is specific to only that file. If you try to use that variable or function in a different file (via a forward declaration) you will get a linking error.
Example:
a.cpp:
static void fn()
{
cout<<"hello a!"<<endl;
}
b.cpp:
void fn();
void gn()
{
fn();//causes linking error
}
This feature allows you to use a function that no other file will ever see, that way you don't cause possible linker errors of a symbol defined multiple times. The preferred method to do this is with anonymous namespaces though:
a.cpp:
namespace
{
void fn() // will be static to a.cpp
{
cout<<"hello a!"<<endl;
}
}
Inside of a class use of static:
If you declare a function or variable as static inside of a class (or struct), it is a class function or class variable. This means that there is only one for that whole class. A class function can only use class variables. A class variable is shared amongst all instances of that class.
class C
{
public:
static void fn()
{
y = 4;//<--- compiling error
// can't access member variable within a static function.
}
int y;
}
This is a great feature to use if you have something that is specific to the class of your objects, but not specific to an instance.
Inside a function use of static:
If you declare a variable as static inside of a function, you can consider that the variable value will persist upon calls. It will only be initialized once.
Example:
//Will print 0, then 1, then 2, ...
void persistentPrintX()
{
static int x = 0;
cout << x << endl;
x++;
}
I personally try to avoid this, and you probably should to. It is not good to have global state. It is better to have functions that given the same input guarantees the same output.
Just like in the English language:
The concept of context sensitive meaning is not specific to C++, you can even see it in the English language.
I am going to screen a movie (Means showing the movie)
The screen on the TV is broken (Means a part of the TV)
Other meanings in other programming languages:
Depending on the programming language there can be a different meaning, but the first thing most people think of when you say static is a class variable/function vs a member variable/function.
I hang around on the ##c++ irc channel on irc.freenode.net and I really like the clarification on static that the bot nolyc is programmed to give. I quote word for word:
When used inside a function, the
static keyword indicates that a
variable is shared between all calls
of the function. When used inside a
class, it indicates that the variable
or function is a member but is not
tied to a specific instance. When
used inside a namespace, it specifies
internal linkage.
I hope that clears things up. I haven't answered all your questions. I would say that you should use the static keyword to do what it was intended to do. Use it as a tool to accompolish your task, if it is the right one for the job. As far as benefits go, I wouldn't worry. If you need to optimize, then think about those effects if there is no other resort.
I hope this helps.