11

I am thinking it is a best practice to declare them as static, as it makes them invisible outside of the module.

What are your thoughts on this?

EvilTeach
  • 28,120
  • 21
  • 85
  • 141

12 Answers12

26

For C++, a better than static is to put it in an unnamed (anonymous) namespace. This is the preferred way to prevent pollution of the Global namespace.

namespace {
void myLocalFunction() {
// stuff
}
}
KeithB
  • 16,577
  • 3
  • 41
  • 45
  • 1
    another advantage about anonymous namespaces is that you can still pass the address of the objects inside it to templates, as they have still extern linkage. – Johannes Schaub - litb Nov 24 '08 at 16:27
  • +1, more info found in this SO thread: http://stackoverflow.com/questions/154469/unnamedanonymous-namespaces-vs-static-functions#154482 – luke Nov 24 '08 at 16:43
  • disadvantage that it's not useful in C. The question was about c/c++ – Ilya Nov 24 '08 at 18:38
  • I didn't notice the C tag. This is a C++ only solution. – KeithB Nov 24 '08 at 20:20
  • Not exactly deprecated, it will continue to work. But namespaces are a better way that is recommended for any new code. – KeithB Nov 25 '08 at 02:30
  • One problem with anonymous namespaces : some debuggers have trouble with setting breakpoints by function name when you use them. –  Nov 25 '08 at 13:11
  • @kshahar: `static` is not deprecated. whoever was proposing that quite quickly realised/got told how wrong they were, and `static` remains a 1st-class feature like it always was. – underscore_d Sep 25 '16 at 09:24
9

If it is truly an function which is internal only to that .c file, then yes. It should help avoid polluting the global namespace. Also, I think that the compiler is able to do some optimizations with calling conventions if the function is static since it knowns no other source file needs to know how to call it. This only really applies to c because as others have noted, c++ has namespaces to address this issue.

Evan Teran
  • 87,561
  • 32
  • 179
  • 238
2

In C++, you should use an anonymous namespace, like so:

// foo.cpp
namespace
{
   class Core { ... };
   void InternalFandango(Core *);
}

void SomeGloballyVisibleFunction()
{
   InternalFandango(&core);
}

Advantage: this is applicable to struct / class declarations, too.
In C, just mark the functions "static". There's nothing against using "static" in C++, too, but I've learnt to prefer the namespace, as it is one single concept that works for all declarations.

peterchen
  • 40,917
  • 20
  • 104
  • 186
2

There was a lot about implementation details and not too much about concept.

Limiting the scope of variable/function etc.. is a good practice indeed. This is a basic concept of object oriented design - you want keep private as private. This way your interface is cleaner and code maintenance is easier. And you will not find one day that changing something that you considered as private broke compilation because somebody in another part of project liked your function and decided to use it.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Ilya
  • 3,104
  • 3
  • 23
  • 30
2

In C, I make everything - functions and variables - static at file scope until I can demonstrate they're necessary outside the file. I'll make things static within a function if only that function will use them and they are not too huge. Basically, if the declaration is bigger than the rest of the function, I may put the declaration outside the function. And, of course, there's a header for the public services provided by a source file.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 2
    one should be careful using static in functions, in regards of reentrancy and multithreading. – Ilya Nov 25 '08 at 19:00
  • 1
    @Ilya: agreed. I try to make things const too whenever possible. It so happens that most of my work does not involve threading. However, I try to avoid global variables; I also try to avoid static variables, both at file and function scope, where I can. – Jonathan Leffler Nov 26 '08 at 05:32
2

Agreed. As a consequence, the prototypes for the static functions must go at the top of the .c file, not in the .h file.

Steve Melnikoff
  • 2,620
  • 1
  • 22
  • 24
1

I think C and C++ have different constraints concerning static: in C you don't have namespaces and .c files are your modules, so it is really really important to put all non-public functions as static to prevent errors!

Piotr Lesnicki
  • 9,442
  • 2
  • 28
  • 26
1

About the only potentially useful property I can think of for this use of "static" in C++, that anonymous namespaces don't provide, is that there's a warning in GCC you can switch on for unused static functions (a form of dead code). You don't get that for unused functions in anonymous namespaces, so in the unlikely event that you want the compiler to tell you when you stop using the function, do it that way.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
1

In C code, make your functions static by default. Only make non-static functions and .h declarations for functions that will be needed by other modules.

In C++ code, put those functions that are local to the file into an anonymous namespace and make them static. In the GNU compiler at least, this will result in the best and smallest code, because no function will be written if all uses are inlined. If you intend it to be inlined, then of course marking it inline is even better than static.

I do not know why g++ writes the uncalled function bodies that are in anonymous namespaces into the output at all, but it does. Functions with hidden visibility seem to show up as well; marked as hidden symbols, but still producing unused code blocks in the object file. GCC probably doesn't understand that the code isn't needed in those cases. Or I am missing something, always possible.

Zan Lynx
  • 53,022
  • 10
  • 79
  • 131
  • 1
    What you described must have been a GCC bug, which I cannot replicate. While this might've been useful info for people using that compiler at that moment in time, It doesn't make sense to extrapolate this to general advice of using both `namespace {` and `static`. The correct response is to file a bug, not to saddle your and other people's code with boilerplate that doesn't make sense from a language perspective. – underscore_d Sep 25 '16 at 09:29
0

If you're using GCC, then you should take a look at the visibility flag (see http://gcc.gnu.org/wiki/Visibility for a full discussion).

It'll hide symbols completely as opposed to marking them unreachable. That reduces the symbol table, and helps decrease link times.

Not only that, it opens the door for more inlining, if that's what you're after.

-1

If by 'module' you just mean a CPP file, you could just place the declaration and the definition right in the CPP file.

John Dibling
  • 99,718
  • 31
  • 186
  • 324
  • 1
    That doesn't really prevent the external symbol from being generated, so it could still conflict with one from another "module" – Evan Teran Nov 24 '08 at 16:09
-1

In C++, you'd declare the function private like this:

class MyClass
{                           
public:                 
void publiclyAccessibleFunction();            
private:                
    void onlyAccesibleFromWithinTheClass();
int some_member_parameter;          
};

Note the onlyAccesibleFromWithinTheClass() function.

thkala
  • 84,049
  • 23
  • 157
  • 201