Reputation: 2876
inline void t1();
void t1(){} // t1 is still inline?
void t2();
inline void t2(){} // t2 is inline?
static void t3(){}
inline void t3(); // t3 is still static?
inline void t4();
static void t4(){} // t4 is still inline?
// "inline function 't4' declared but never defined", are these not the same function?
extern void t5();
inline void t5(){} // t5 is still extern?
inline void t6(){}
extern void t6(); // t6 is still inline?
int main(){
return 0;
}
Please note in the above snippet some functions are first fully defined and their prototype is changed afterwords with a different storage type, or inlined.
I have the following questions:
1- Are the storage types, or the inline
state of the functions persistent as per comments?
2- Why compiler warns that t4
is declared but never defined? isn't static void t4(){}
the definition?
Upvotes: 1
Views: 100
Reputation: 222660
C 2018 6.7.4 7 says:
… For a function with external linkage, the following restrictions apply: … If all of the file scope declarations for a function in a translation unit include the
inline
function specifier withoutextern
, then the definition in that translation unit is an inline definition.
6.9 5 says:
An external definition is an external declaration that is also a definition of a function (other than an inline definition) or an object.
For each of your cases except t3
, the identifier appears with external linkage and it is not true that all of the file scope declarations include inline
. Therefore, there are no inline definitions for those cases.
inline void t1(); void t1(){} // t1 is still inline?
There is no inline definition, per above.
void t2(); inline void t2(){} // t2 is inline?
There is no inline definition, per above.
static void t3(){} inline void t3(); // t3 is still static?
C 2018 6.2.2 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
…
Therefore, for inline void t3();
, we may read extern inline void t3();
. Then 6.2.2 4 says:
For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration…
Therefore, the linkage of t3
in extern inline void t3();
is the same as in the prior declaration static void t3(){}
, so it is internal.
inline void t4(); static void t4(){} // t4 is still inline? // "inline function 't4' declared but never defined", are these not the same function?
Per above, there is no inline definition of t4
.
Further, inline void t4();
declares t4
with external linkage, and static void t4(){}
declares it with internal linkage, and 6.2.2 7 says:
If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined.
extern void t5(); inline void t5(){} // t5 is still extern?
Yes, per 6.2.2 5, above.
inline void t6(){} extern void t6(); // t6 is still inline?
There is no inline definition, per above. This case is equivalent to fahr
in example 1 in C 2018 6.7.4 10, where the commentary explicitly says that the definition of the function is an external definition.
Upvotes: 1