Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win


static keyword on none member functions - why???

Posted on 2011-03-23
Medium Priority
Last Modified: 2012-05-11
Ah hello.

I would like some clarification on the use of "static" for a none member function, please.

From what I have read, it seems that the static keyword limits the function to be callable from within the .cpp file it is defined in.  But how is this different to when I don't have the static keyword: the function is literally only visible in the .cpp so how can it be callable from anywhere else?  I mean, if we have...
// .h
int GetInt();

// .cpp
int GetInt() 
	return 42;

Open in new window

...then clearly any file that includes the header can call GetInt().  So how can we possibly call GetInt() if we can't see its declaration via the header?

If I change the .cpp to have the static keyword, even though the function is "visible" via the header, I then get linker errors (unresolved external symbol "GetInt()") when I try and call it outside of the defining .cpp.  I guess this is so the .cpp can use the functions without having to bother about the order in which they are definedin the .cpp, whilst still preventing them from being callable outside that same .cpp.  Is this right?

Apart from this, the whole concept of static on a none member function hence seems totally redundant to me...
Question by:mrwad99
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2
  • 2
  • +2
LVL 35

Expert Comment

ID: 35198162
a non-static function can be called from everywhere by only including the header file where the function was declared (or using a declaration of the function made in the calling source separately) .

the compiler is happy with that and when building the application the linker will bring the two modules together or give an error message when it can't find the called function.

LVL 19

Author Comment

ID: 35198746
So what exactly is the point of having the static keyword on a function that is not declared in a header file and defined in a single .cpp?  It does not add anything: we cannot attempt to call it from another module as the compiler will flag it as an error since it cannot "see" it, so we never get to the stage of the linker being unable to find it...
LVL 32

Accepted Solution

phoffric earned 220 total points
ID: 35199701
    int foo()  {...}

If foo is not declared in any .h file, then it can still be used in other .cpp files with this declaration:
    extern int foo();


    static  int foobar()  {...}

This foobar() cannot be used in other .cpp files even if it is declared in a .h file or by using an extern declaration.
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

LVL 32

Expert Comment

ID: 35199724
The "extern" in "extern int foo();" is optional for global functions.
"extern" is not optional for global variables.
LVL 16

Assisted Solution

imladris earned 120 total points
ID: 35199754
A non-static non-member function is, in fact, visible in, and can be called by, functions in other files. We don't, by and large, do stuff like that anymore, because it would involve calling the function without the use of the prototype, which is there to make sure the arguments match. However, C was originally written like that, and so C++ supports it as well.

Thus the static keyword/storage class, which guarantees that the function can only be used in the file it is defined in.
LVL 32

Expert Comment

ID: 35199808
There are distinctions between compiler errors and builder errors.

The compiler will give an error if a function is used without it being previously declared (or defined). If you have in a .h file:
    int foobar() ;
or in your .cpp file:
    int foobar() ;
then if you use it in a filename.cpp file, the compiler will not issue an error, since you have declared foobar().

In linux, if you wrote:
    g++ -c filename.cpp
then there should be no errors in compiling with calling foobar() since it is declared in one of the two ways.
LVL 40

Assisted Solution

evilrix earned 160 total points
ID: 35200550
Hey mrwad99,

Long time no see (*waves*) :)

Although various answers have been given here none of them have actually explains the specific details of using static with a free functinn; so I will...

Symbols (functions, variables types etc) have what is called "linkage". This "linkage" basically defines whether the symbols that exist in your program can be seen by the linker (the stage after the compiler had finished) and, if so, under what scope.

Specifically, the C++ standard says the following about linkage...

"A name is said to have linkage when it might denote the same object, reference, function, type, template,
namespace or value as a name introduced by a declaration in another scope:

— When a name has external linkage, the entity it denotes can be referred to by names from scopes of other translation units or from other scopes of the same translation unit.

— When a name has internal linkage, the entity it denotes can be referred to by names from other scopes in the same translation unit.

— When a name has no linkage, the entity it denotes cannot be referred to by names from other scopes."

Normally, a free standing function will have external linkage but by defined it as static the linkage is changed to internal.

"A name having namespace scope has internal linkage if it is the name of an object, reference, function or function template that is explicitly declared static"

The use of static for this purpose, in C++, is now deprecated and should be avoided.

"The use of the static keyword is deprecated when declaring objects in a namespace scope (see annex D);
the unnamed-namespace provides a superior alternative.

D.2 static keyword - The use of the static keyword is deprecated when declaring objects in namespace scope."

Instead, you should use an anonymous namespace.

An unnamed-namespace-definition behaves as if it were replaced by

namespace unique { /* empty body */ }
using namespace unique;
namespace unique { namespace-body }

Open in new window

where all occurrences of unique in a translation unit are replaced by the same identifier and this identifier
differs from all other identifiers in the entire program.82)

namespace { int i; } // unique::i

void f() { i++; } // unique::i++

namespace A {
   namespace {
      int i; // A::unique::i
      int j; // A::unique::j
   void g() { i++; } // A::unique::i++

using namespace A;
void h() {
   i++; //error: unique::i or A::unique::i
   A::i++; // A::unique::i
   j++; // A::unique::j

Open in new window

LVL 19

Author Closing Comment

ID: 35205771
Right, many thanks for helping with the clarification of this.


I had completely forgotten about the "extern" keyword, which is strange having used it so many times previously.  Ultimately, this is the answer to my question.


Good God, I have not heard your name since I first joined EE back in 2002, and you helped me understand dynamic memory allocation in C (http:Q_20417450.html)!  Good to see you are still on this site!  Thanks for participating here!


LTNS indeed!  I do hope you are well.  Thanks for this; the stuff on namespaces was useful.  The only thing I would like to say is where you talk about "unique": it took me a while to understand exactly what you meant there, so I googled it and came across http://msdn.microsoft.com/en-gb/library/yct4x9k5.aspx (which could have been where your example code came from):  the use of italics in "unique" on that page highlight the fact that "unique" is a compiler generated value, which made the penny drop...hehe.
LVL 40

Expert Comment

ID: 35207161
>> I do hope you are well.  

Very well. I hope you are too - welcome back to the cool zone :)

>> where you talk about "unique": it took me a while to understand

Oooh, my apologies - this was a direct copy/paste from the C++ standard.... if I have cause to do so again I will be sure to add some additional verbiage to explain things. Thanks for the feedback.
LVL 32

Expert Comment

ID: 35207363
Only Stroustrup, you, and one other EE expert can quickly interpret the C++ standard. So it is alway best to clarify when quoting from this standard.

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
Suggested Courses

610 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question