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?

12 Answers 12

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
}
}
7
  • 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. Commented Nov 24, 2008 at 16:27
  • +1, more info found in this SO thread: stackoverflow.com/questions/154469/…
    – luke
    Commented Nov 24, 2008 at 16:43
  • disadvantage that it's not useful in C. The question was about c/c++
    – Ilya
    Commented Nov 24, 2008 at 18:38
  • I didn't notice the C tag. This is a C++ only solution.
    – KeithB
    Commented Nov 24, 2008 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
    Commented Nov 25, 2008 at 2:30
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.

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.

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.

2
  • 2
    one should be careful using static in functions, in regards of reentrancy and multithreading.
    – Ilya
    Commented Nov 25, 2008 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. Commented Nov 26, 2008 at 5: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.

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.

0
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!

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.

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.

1
  • 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. Commented Sep 25, 2016 at 9: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.

1
  • 1
    That doesn't really prevent the external symbol from being generated, so it could still conflict with one from another "module"
    – Evan Teran
    Commented Nov 24, 2008 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.

1
  • the OP was talking about modules, i.e. separately compiled source files and their headers, not objects. Commented Sep 25, 2016 at 9:31

Not the answer you're looking for? Browse other questions tagged or ask your own question.