35

I've recently seen a bit on SO about the static keyword before a function and I'm wondering how to use it properly.

1) When should I write the keyword static before a non-member function?

2) Is it dangerous to define a static non-member function in the header? Why (not)?


(Side Question)

3) Is it possible to define a class in the header file in a certain way, so that it would only be available in the translation unit where you use it first?

(The reason that I'm asking this is because I'm learning STL and it might be a good solution for my predicates etc (possibly functors), since I don't like to define functions other than member-functions in the cpp file)

(Also, I think it is related in a way to the original question because according to my current reasoning, it would do the same thing as static before a function does)

EDIT

Another question that came up while seeing some answers:

4) Many people tell me I have to declare the static function in the header, and define it in the source file. But the static function is unique to the translation unit. How can the linker know which translation unit it is unique to, since header files do not directly relate to a source file (only when you include them)?

xcrypt
  • 3,276
  • 5
  • 39
  • 63

3 Answers3

29

static, as I think you're using it, is a means of symbol hiding. Functions declared static are not given global visibility (a Unix-like nm will show these as 't' rather than 'T'). These functions cannot be called from other translation units.

For C++, static in this sense has been replaced, more or less, by the anonymous namespace, e.g.,

static int x = 0;

is pretty equivalent to

namespace {
  int x = 0;
}

Note that the anonymous namespace is unique for every compilation unit.

Unlike static, the anonymous namespace also works for classes. You can say something like

namespace {
 class Foo{};
}

and reuse that class name for unrelated classes in other translation units. I think this goes to your point 3.

The compiler actually gives each of the symbols you define this way a unique name (I think it includes the compilation time). These symbols are never available to another translation unit and will never collide with a symbol from another translation unit.

Note that all non-member functions declared to be inline are also by default static. That's the most common (and implicit) use of static. As to point 2, defining a static but not inline function in a header is a pretty corner case: it's not dangerous per se but it's so rarely useful it might be confusing. Such a function might or might not be emitted in every translation unit. A compiler might generate warnings if you never actually call the function in some TUs. And if that static function has within it a static variable, you get a separate variable per translation unit even with one definition in a single .h which might be confusing. There just aren't many (non-inline) use cases.

As to point 4, I suspect those people are conflating the static member function meaning of static with that of the linkage meaning of static. Which is as good a reason as any for using the anonymous namespace for the latter.

smparkes
  • 13,807
  • 4
  • 36
  • 61
  • I suppose you would write these code samples in the header? If so, could you please explain how the linker can know what translation unit to bind it to? (preferably in your answer) – xcrypt Dec 06 '11 at 21:28
  • I've never used the anonymous namespace in a header. I use it for helper functions/classes that are to be used only within the scope of one translation unit. I'm afraid I don't exactly follow what you mean by _so that it would only be available in the translation unit where you use it first_. You know translation units are the whole post-CPP mess, right? Individual source files are not translation units. – smparkes Dec 06 '11 at 21:40
  • But if you define something in the source file, it is already unique to the translation unit, right? So why *not* use it in the header? I'm afraid I don't exactly follow your last question either. Are translation units not the *cpp file + the headers your include in them, converted by the compiler into a .obj file*? – xcrypt Dec 06 '11 at 21:45
  • 1
    Last line is right. A translation unit (TU) is (commonly) whatever produces a .o/.obj. I think the confusion is your first line: even if you don't mention it in a header, if a function/class declaration doesn't have `static` or isn't in the anonymous namespace, it's global and potentially will collide with a definition in another TU. – smparkes Dec 06 '11 at 21:53
  • I think your answer is the best yet, but I don't think it's complete. If you could only answer '2)' and '4)' at all/better, I would be inclined to accept it. Not pushing you of course, just saying. – xcrypt Dec 06 '11 at 22:05
  • I didn't remark on some of those because I didn't really understand them. But thinking more of the various meanings of `static`, I think I do ... – smparkes Dec 06 '11 at 22:24
  • 1
    As far as 4): short answer: don't do it. The "translation unit" is what the compiler sees to create the .o(bj): headers + implementation. In your case (static myvar, static my_function) I would NOT put them in .h - only in .cpp. IMHO... – paulsm4 Dec 06 '11 at 22:30
  • (I didn't mention after my last comment that I added to the original answer ...) – smparkes Dec 06 '11 at 22:36
  • Great answer... Clarifies a lot to me (and hopefully a whole bunch of other people) I'd give you +2 if I could ;) – xcrypt Dec 06 '11 at 23:54
5

The keyword "static" is overloaded to mean several different things:

  • It can control visibility (both C and C++)

  • It can persist a variable between subroutine invocations (both C and C++)

    ... and ...

  • It can make a method or member apply to an entire class (rather than just a class instance: C++ only)

Short answer: it's best not to use ANY language facility unless

a) you're pretty sure you need it

b) you're pretty sure you know what you're doing (i.e. you know WHY you need it)

There's absolutely nothing wrong with declaring static variables or standalone functions in a .cpp file. Declaring a static variable or standalone function in a header is probably unwise. And, if you actually need "static" for a class function or class member, then a header is arguably the BEST place to define it.

Here's a good link:

http://www.cprogramming.com/tutorial/statickeyword.html

'Hope that helps

paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • @Alessandro Pezzato - I didn't mark anybody down. But I appreciate your support, if that was your intent :) Thank you. – paulsm4 Dec 06 '11 at 22:26
  • Good answer, but (imo) incomplete / too few details. I didn't vote down though. – xcrypt Dec 07 '11 at 00:06
4

You should define non-member functions as static when they are only to be visible inside the code file they were declared in.

This same question was asked on cplusplus.com

Drew Chapin
  • 7,779
  • 5
  • 58
  • 84
  • 1
    @kol - strictly speaking 'translation unit' which is generally the same as the object file. So if you include the header in multiple 'c' files it will end up in each of them – Martin Beckett Dec 06 '11 at 21:11
  • Use of "translation unit" instead of "code file" would probably make a better answer, although the behavior for CPP files is basically as described. – André Caron Dec 06 '11 at 21:12
  • But should I define the static function in the header or the cpp? Because if I declare and define a non-static function in the cpp, it is also bound to that translation unit right? If I'd define it in the header, then how does the linker know which translation unit it's unique to? If I'd declare it in the header, and define it in the cpp, well, (the latter) how can the linker know? – xcrypt Dec 06 '11 at 21:20
  • Ideally, you would be declaring it in the header file, and defining it in the code file (cpp file). – Drew Chapin Dec 06 '11 at 21:21