Member function with static linkage
Asked Answered
H

3

92

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?

Heptagon answered 8/7, 2015 at 23:41 Comment(2)
Possible duplicate of Static member functions error; How to properly write the signature?Beholden
@phuclv, True but the explanation provided by the accepted answer here is useful.Cistern
H
216

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.

Horatius answered 8/7, 2015 at 23:46 Comment(3)
That makes sense, thanks! I suppose the compiler could differentiate between static void some_function() { ... } and static void Foobar::some_method() { ... } and treat them differently, but it would make it harder for humans to parse since the two have different semantics and very similar syntax. I'm not too happy with the solution, since it makes it harder to see that a method is static by looking at its implementation (without comments), but oh well.Heptagon
When you sey It's basically a normal function that's nested inside of the scope of the class by normal do you mean global?Chicoine
It's such an easy mistake to make in C++, many tutorials (like this one) don't even touch on that subtle differenceBacteriology
P
10

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.

Pillion answered 5/8, 2020 at 7:8 Comment(0)
P
0

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.

Phalanstery answered 26/11, 2022 at 23:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.