views:

137

answers:

3

i have this files:

//Q2a.h
#ifndef Q2A_H
#define Q2A_H

inline int MyFactorial(int a)
{
if (a < 2)
    return 1;
return a*MyFactorial(a-1);
}

int NumPermutations(int b);
#endif

//Q2a.cpp
#include "Q2a.h"

int NumPermutations(int b)
{
    return MyFactorial(b);
}

and file with the main- Q2b.cpp

i notice that the compiler usually ignore the inline decleration when there are recursive functions . but my question is why if i remove the inline declaration, i can do:

g++ -Wall -g -c Q2a.cpp -o Q2a.o
g++ -Wall -g -c Q2b.cpp -o Q2b.o

those are fine, but in the linkage stage:

g++ -Wall -g -c Q2a.o Q2b.o -o Q2

i get an error: multiple definition of `MyFactorial(int)

+1  A: 

Because when you #include "Q2a.h", you're essentially doing a text substitution of the contents, so both Q2a.cpp and Q2b.cpp end up defining a function called MyFactorial(). You either need to use inline, or define the function in one of the source files.

Note that using inline won't help very much with a recursive function!

Oli Charlesworth
Tail-recursive `inline` is reasonable, but this isn't such a case.
Potatoswatter
+1  A: 

With GCC declaring a function as inline will just hint the compiler to inline the function. However, the compiler will still generate a non-inline function that you can call from a different compilation unit.

These functions had a name collision in your case. Simply said: inline doesn't imply static.

What you want to do is to declare the functions as static inline

This will tell the compile that you want your function inline, and - if the compiler decides to inline it - no static version of the same function is required. It otoh the compiler can't inline the function it will make sure that the function is static, e.g. the name of the function is local to the C-file and no name collisions during linking of the program will occur.

Hint:

Compilers have different behaviour. If you want to compile the code on a different platform in the future make sure that you hide the definition in a macro.

For example I have to use static inline for the GCC and Visual Studio and a simple _inline for the TI Code Composer DSP/embedded ARM compiler. The later compiler doesn't understand a plain inline because it is non-standard and won't understand static _inline either.

Nils Pipenbrinck
From the Standard: "7.1.1 Storage class specifiers— The storage class specifiers arestorage-class-specifier:`auto register static extern mutable`**At most one storage-class-specifier shall appear in a given decl-specifier-seq."**
Potatoswatter
`inline` is like static, but superior if the function definitions are identical. `static` says "this will be defined in multiple files, maybe differently. `inline` says "this will be defined in multiple files, interchangeably." The code-generation hint is a secondary effect.
Potatoswatter
+1  A: 

When you declare a function inline you change the rules that apply for the definitions of your function.

A non-inline function must only be defined once in a program; in contrast an inline function may be defined in multiple translation units, although the definitions must be identical and the function must be defined in every translation in which it is used.

By removing inline, you are removing the exemption from the "one definition rule" that you had previously.

Charles Bailey