简体   繁体   中英

Mixing the usage of static, extern and inline keywords between definition and declaration

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?

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 without extern , 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM