With respect to the first, "inline function" example, you say (highlighting added to function names),
Since fun1
is a inline definition in temp2.c, it will be seen as
undefined from temp1.c. So external declaration in temp1.c made
temp1.c to access fun1
from temp2.c.
Your explanation is incorrect, or at least misworded. In this example, your temp2.c does not provide an external definition of function fun1()
. The declaration in temp1.c says that there is an external definition somewhere, but temp2.c is not that place. There needs to be an external definition provided by some other translation unit. Function fun1
in temp2.c is an inline function because it is declared with the inline
keyword (that's all it means to be an "inline function"), but the definition of fun1
in that file is not an inline definition, because temp2.c contains another declaration of its identifier that does not include the inline
keyword. Since fun1
is declared with (implicitly) external linkage, that is an external definition of fun1
. Anyone can call it. To get an inline definition of a function, every declaration of its identifier in the TU must include the inline
keyword and must omit the extern
keyword.
Standard C does require the function to be declared in temp1.c if it is to be called from that TU, but nothing you put in that file could enable code within to access an inline definition of fun1
from a different TU. Only external definitions are accessible across TUs -- that's what being an external definition means.
Note: The original (now stricken-out) text of this part of this answer supposed that temp2.c indeed did provide an inline definition of function fun1
, because I overlooked the flaw(?) in the declarations.
I am confused as in the quotes it
is saying "separate external definition" instead of external
declaration.
A function definition comprises a declaration of that function, but not every function declaration is part of a definition. We must be careful with our wording here. There is no meaningful sense of an "external function declaration" in C, in that no declaration has a scope wider than its translation unit.
But one can, and often does, have (local) declarations of functions with external linkage. This is the default, applicable to all function declarations that do not include the keyword static
. That default can be made explicit by use of the extern
keyword, and that happens to have additional significance for declarations of inline functions.
An external function definition, on the other hand, is one that can be accessed by name from another translation unit. An inline definition explicitly is not an external definition. Thus, your first example declares that there is a function fun1
with external linkage, but does not if all the declarations of that identifier carried the inline
keyword and not extern
then it would not provide a corresponding external definition of that function. If that function is were called, even from a source file that provides an inline definition, then the absence of an external definition is would be an error.
With respect to the second, "extern inline function" example, you say (highlighting added to function names),
Since fun1
is extern inline function, it can be called from temp1.c.
Let's separate out the properties here.
fun1
is (still) declared as a function with external linkage.
- The presence of the
inline
specifier in the declaration that is part of its definition makes it an inline function.
- The presence of the explicit
extern
specifier on a declaration of that function in the same translation unit as a definition makes the definition in that TU an external one.
It is the fact that the definition in temp2.c is an external one that makes it callable from temp1.c.
The only difference what I observed is, no need of explicit
declaration of the extern inline function where it is defined.
There is no need for a forward declaration of fun1()
in the first example, either. There would be a need for a forward declaration in both cases if temp2.c contained a call to fun1
prior to that function's definition. There is no difference here.
Update:
You are more or less right. Your two alternatives are different ways to declare an an inline function with external linkage and to provide an external definition for it. Instead, the thing you should be comparing to, and to which the original text of this answer was erroneously addressed, would be this:
#include <stdint.h>
inline int32_t fun1(void);
inline int32_t fun1(void)
{
return 0;
}
or, equivalently, this:
#include <stdint.h>
inline int32_t fun1(void)
{
return 0;
}
In those cases, the provided definition of fun1
is an inline definition, accessible only from the translation unit of temp2.c. Of course, that's not useful unless there is code in that TU that actually calls the function.
Is it the only difference ? else what are the other major difference
and the scope of inline and extern inline functions ?
You are doing yourself a disservice by attempting to set up "inline" and "extern inline" as classes of functions. There are inline functions and non-inline functions. There are function identifiers with internal linkage and those with external linkage. There are inline function definitions, internal ones, and external ones, and appearance of a function declaration in a TU does not necessarily require a definition in the same TU. These combinations (and only these) of those properties are possible:
- function identifier is declared with external linkage, function is not an inline function, and an external definition of the function appears in the TU
- function identifier is declared with external linkage, function is not an inline function, and no definition of the function appears in the TU with the declaration. If the function identifier is referenced in the TU then an external definition appears in a different TU.
- function identifier is declared with external linkage, function is an inline function, and an inline definition of the function appears in the TU. If the function identifier is referenced in the TU then an external definition appears in a different TU.
- function identifier is declared with external linkage, explicitly, function is an inline function, and an external definition of the function appears in the TU
- function identifier is declared with internal linkage, the function is not an inline function, an internal definition of the function appears in the TU
- function identifier is declared with internal linkage, the function is not an inline function, an no definition of the function appears in the TU. The function identifier is never referenced in that TU.
- function identifier is declared with internal linkage, the function is an inline function, an inline definition of the function appears in the TU
A function identifier declared with external linkage in a given TU refers refers to an external function definition, which may appear in a different TU.
A function identifier declared with internal linkage in a given TU refers refers to an internal or inline function definition in the same TU.
An inline function declaration may have either external or internal linkage, in either case, an inline definition of that function must appear in the same TU. If the function identifier has external linkage (in that TU) and an inline function definition then it is left to the discretion of the implementation whether and where the inline definition or the (required) external definition elsewhere is used within that TU.
Update:
Upon reflection, your characterization of functions themselves as "inline functions" and "extern inline functions" seems to reflect the idea that inline character of a function is globally associated with the function's identifier (e.g. fun1
), at least for identifiers with external linkage. This is not the case, as I hope my rather lengthy discourse has conveyed.
Inline character of a function identifier is a per-TU property, and inline character of a function definition is a separate, per-definition property. If in any TU you declare a given function to be an inline function, then you must provide a definition of that function in that TU. An external definition of a function from a different TU does not satisfy that requirement, even if the function is declared to be an inline function in the TU in which the definition appears.