There are several rarely used keywords in C. There is asm, register, volatile, union, extern, static.... Each is useful in certain situations but those situations arise with varying frequencies. Extern and static are the most used of the least common keywords but many people do not know what they really mean.
Part of the problem is that these keywords effectively mean different things depending on what they are used on. Static, when applied to a storage definition in a function, means "shared". To declare a variable static causes it to become part of the global data. So if you declare
static int foo;
foo will be shared by every invocation of the enclosing function. Whatever value you set foo to will still be there when the function is called the next time. I don't particularly recommend this use of static. The
strtok function from the C standard library uses this trick to remember where the last token ended. However this means that you can only strtok one thing at a time and the function cannot be used by two threads at the same time. Because of that shared state the invocations would trample each other and neither thread get the correct information.
Static when applied to a function deceleration means something different. In that case static means that the function is not visible outside the current file (translation unit is the exact terminology). So even if you put a forward deceleration of the function in the header file the linker will be unable to find it if you try to use it. Global variables declared static follow the same rules as when a function is declared static. By making functions and globals that are not part of the interface of that module static, you reduce name-space pollution (of the compilation symbols) and can speed up the linking step of your compilations.
Extern is the sort of the opposite of static. When applied to global data it makes the variable visible outside the file. Think of it like this; an extern deceleration is exactly like a forward deceleration of a function in a header file. And should be used in the same way. If you have global data that is to be used in a public interface you should use extern to forward declare it in the header file.
It is apparent from what I've seen at work that many really don't know how to use extern and static. So here are my simple rules.
- If you write a function that is not and should not be used outside the current file declare it static. Also put it's forward deceleration (if you need one) in the C file not the h file.
- If you have global data that you want to make visible. Declare the data as extern in the header file and as normal global data in the file C file.
No comments:
Post a Comment