What's the difference between static inline void and void?

static means it can't be referenced from another compilation unit (source file). "Referenced" means called, or otherwise referred to by name, e.g. assigned to a function pointer.

inline is a hint to the compiler that the function's code should be generated inline at the place it is called, rather than generated as a separate function to be branched to. This is normally done for performance reasons. To deal with Microsoft's quote:

the compiler does not inline a function if its address is taken or if it is too large to inline.

An inlined function has no address, since it doesn't exist as a separate entity. Its code is just intertwined seamlessly with the code it's called from. So, if you take the address of a function (e.g. to assign to a pointer) then the compiler has to generate it as a real function, and cannot inline it.

void means the function does not return a value.


Having looked at your code sample, I'd guess that there is a separate definition of CGauss() somewhere, which is being called from file1.c, whereas file2.c is calling its own private version. Either that, or file1.c is #includeing file2.c. Which would be nasty.


static only means something when you have more than one source file. It specifies that the static function or variable cannot be accessed from functions in a different file.

inline is a compiler optimization that speeds up your code in certain cases. Whenever you call a function, there is some overhead associated with it. So what the compiler can do is get rid of the function all-together by copy+pasting (almost) the inlined code.

Here's an example of inlining:

int dotproduct(int x1, int y1, int x2, int y2) {
    return multiply(x1,x2)+multiply(y1,y2);
}

inline int multiply(int a, int b) {
    return a*b;
}

The compiler will turn this into:

int dotproduct(int x1, int y1, int x2, int y2) {
    return x1*x2+y1*y2;
}

If you want to be fancy, you can also inline the dotproduct function ;)

Note that the inline keyword is simply a nudge to the compiler to inline certain functions. It may or may not actually do it depending on it's own judgement.


The static keyword

Defining a C function static means (as the docs say) that this function can only be accessed from the source file it is defined in. The term 'reference' in this sence means either calling this function or for instance taking a function pointer to it.

Inlining

Normally, when you write a function in C, the compiler generates the machine code for this function:

foo:
   /* some machine code */
   ret

Every time you call this function, the compiler inserts an instruction such as

  call <foo>

into the caller's machine code, which means nothing else than "jump to foo, execute what you find there and when you encounter a ret instruction, return to this location."

In contrast, for inline functions, the compiler does not generate a separate function foo(), but instead inserts the machine code for function foo into every call site. When executing this code, this has the same effect.

So why do we do that? Inlining code has the advantage of saving you two jumps (the call and the respective ret), which makes your code execute a bit faster. As a downside, your code gets larger, because you insert the machine code on every call site instead of having only one copy of a callable function. That's why you usually only inline small functions.

Also, you cannot take function pointers to inline functions, and debugging becomes harder, because you cannot set a breakpoint on an inline function easily.

Therefore, inlining is left for the compiler as an optimization option and by using a keyword such as C++'s inline, your inline directive, or GCC's __attribute((inline)), you only give the compiler a hint that inlining might be worth a try here.