GCC can compile and link the following .c files into an executable:
main.c
#include <stdio.h>
#include "addsub.h"
int main(void)
{
printf("%d %d\n", add(1, 2), sub(1, 2));
return 0;
}
addsub.c
#include "addsub.h"
inline int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return add(a, -b);
}
addsub.h
#ifndef ADDSUB_H__
#define ADDSUB_H__
int add(int, int);
int sub(int, int);
#endif
According to C11, 6.7.4 Functon specifiers, paragraph 7:
[...] For a function with external linkage, the following restrictions apply: If a function is declared with an
inline
function specifier, then it shall also be defined in the same translation unit. If all of the file scope declarations for a function in a translation unit include theinline
function specifier withoutextern
, then the definition in that translation unit is an inline definition. An inline definition does not provide an external definition for the function, and does not forbid an external definition in another translation unit. [...]
The extern
keyword has not been used in any of the function declarations above, so is GCC correct in providing an external definition of the add
function in "addsub.c"?
In 6.2.2 Linkages of identifiers, paragraph 5 says:
If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier
extern
. [...]
However, that does not seem to justify adding external linkage to the inline add
function when the extern
keyword is omitted.
The condition “If all of the file scope declarations for a function in a translation unit include the inline
function specifier without extern
” is not satisfied because addsub.c includes addsub.h, which contains int add(int, int);
, which is a declaration of add
that does not include the inline
function specifier.