Search code examples
cfunctionlinkerforward-declarationlinkage

Is the function my_func exposed to the linker or not for this example?


I wish to further understand if the function my_func() is exposed to the linker for the following much reduced example. The basics are which takes precedence, the forward-declaration or the declaration ?

I guess the forward-declaration, but why ? Can somebody please explain, ref. to K & R is fine

static int my_func(void);

<Use my_func here>

int my_func(void)
{
  return 1;
}

what if the example is modified to be

static int my_func(void);
int my_func(void);

<Use my_func here>

int my_func(void)
{
  return 1;
}

Solution

  • This

    static int my_func(void);
    

    is already a function declaration with the internal linkage.

    So the following declaration

    int my_func(void);
    

    is redundant.

    These declarations

    static int my_func(void);
    int my_func(void);
    

    are equivalent to

    static int my_func(void);
    extern int my_func(void);
    

    From the C Standard (6.2.2 Linkages of identifiers)

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

    And

    4 For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible,31) 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. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.

    Thus in this code snippet

    static int my_func(void);
    int my_func(void);
    
    <Use my_func here>
    
    int my_func(void)
    {
      return 1;
    }
    

    you have three declarations of the same function with the internal linkage and the declaration

    int my_func(void);
    

    as it was said early is redundant.

    It means that the function is not visible in other translation units. Or if the declaration of the function with the storage class specifier static is placed in a header then each translation unit that includes the header has its own function with the same name.

    If you will write instead like

    int my_func(void);
    static int my_func(void);
    

    then the behavior is undefined because the same name is defined as having external and internal linkages.

    From the C Standard (6.2.2 Linkages of identifiers)

    7 If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined.