cgcclanguage-lawyerinline

Is `extern` required to make an inline function definition externally linked?


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 the inline function specifier without extern, 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.


Solution

  • 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.