简体   繁体   中英

Redeclaring a non-static inline function as extern

Is it legal C to redeclare an inline function as extern in an inner scope?

Would the code below be legal C with or without MACRO being truthy?

#if MACRO
    enum { have_macro = 1 };
    inline int foo(void){ return 43; }
#else
    enum { have_macro = 0 };
#endif
int main()
{
    if(have_macro){
        extern int foo(void);
        return foo();
    }else
        return 0;
}
extern int foo(void); //maybe instantiate

Is it legal C to redeclare an inline function as extern in an inner scope?

Yes, but if you have it also defined without inline in other translation unit, it's ambigious which one is used.

On a similar topic, can I link with an instantiated non-static inline by declaring it extern in another file?

No, inline functions are only visible to compilation unit they are declared and defined in.

6.7.4 Function specifiers

  1. Any function with internal linkage can be an inline function. 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. An inline definition provides an alternative to an external definition, which a translator may use to implement any call to the function in the same translation unit. It is unspecified whether a call to the function uses the inline definition or the external definition.

Preliminary note for non-language-lawyers: the term external definition in C is not to be confused with extern or external linkage . It means, roughly, "any definition that appears at file scope and is not an inline definition". For example, a static function definition would be an external definition. See section 6.9 of the C17 standard for more detailed coverage.

Also note that the term inline definition has its own quirks; a function definition with inline keyword may be either an inline defintion or an external definition depending on other things which I will cover below.


For the following code (which results from MACRO being defined):

inline int foo(void){ return 43; }
int main()
{
    if(1){
        extern int foo(void);
        return foo();
    }else
        return 0;
}
extern int foo(void);

The first line provides an external definition for foo , and not an inline definition:

The rule is that if there is a definition of a function with external linkage that has the inline keyword, and a file-scope declaration of that function without the inline keyword, then the function definition is an external definition. See C17 6.7.4/10 for almost this exact example. The block-scope declaration makes no difference.

This code is OK so far, however it would be undefined behaviour if another translation unit also provided an external definition for foo .


For the version without MACRO:

int main()
{
    if(0){
        extern int foo(void);
        return foo();
    }else
        return 0;
}
extern int foo(void);

This code is also fine so far, but it would be undefined behaviour if there were not exactly one definition of the foo function in the program somewhere. (C17 6.9/5) Hiding the code behind if(0) does not get away from the one definition rule.

inline does nothing at language grammar level, it doesn't change function signature, linkage or visibility.

extern is a declaration, you must declare the function with the same signature as definition. And inline doesn't affect function signature and visibility only static does.

As long as you doesn't violate one definition rule in the same translation unit, it is fine. If multiple units exports same weak definition, random one be chosen at link or load time.

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