Solved

static keyword on none member functions - why???

Posted on 2011-03-23
10
444 Views
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...
0
Comment
Question by:mrwad99
  • 4
  • 2
  • 2
  • +2
10 Comments
 
LVL 32

Expert Comment

by:sarabande
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.

Sara
0
 
LVL 19

Author Comment

by:mrwad99
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...
0
 
LVL 32

Accepted Solution

by:
phoffric earned 55 total points
ID: 35199701
.cpp
    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();

===

.cpp
    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.
0
 
LVL 32

Expert Comment

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

Assisted Solution

by:imladris
imladris earned 30 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.
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 32

Expert Comment

by:phoffric
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.
0
 
LVL 40

Assisted Solution

by:evilrix
evilrix earned 40 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

0
 
LVL 19

Author Closing Comment

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

phoffric:

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.

imladris:

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!

RX:

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.
0
 
LVL 40

Expert Comment

by:evilrix
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.
0
 
LVL 32

Expert Comment

by:phoffric
ID: 35207363
evilrix,
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.
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
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.

707 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now