CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Jan 2009
    Posts
    19

    "inline" and linking errors

    I'm wondering if anyone has a good explanation of this. Essentially, when using a template specialization, the "inline" keyword is making the difference between compilable and non-compilable code (gcc v4.1.2). Here's my bare-bones example:
    Code:
    //file: header.h
    #ifndef HEADER_H
    #define HEADER_H
    
    #include <iostream>
    
    template<class T>
    void foo(T val){
      std::cout << "foo<T>("<<val<<")\n";
    }
    
    template<>
    inline void foo(double val){
      std::cout << "foo<double>(" << val <<")\n";
    }
    
    #endif
    Code:
    //file: main.cpp
    #include "header.h"
    
    int main(){
      double x=4;
      foo(x);
      return 0;
    }
    Code:
    //file:  somecode.cpp
    #include "header.h"
    void somecode(){}
    This compiles fine if the "inline" keyword is included in the template specialization in header.h, but without "inline", the compiler spits out "multiple definition of `void foo<double>(double)'" at the linking phase. Does anybody have a good explanation of the role of "inline" in this example?

  2. #2
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: "inline" and linking errors

    Inline functions never make it to the linker. They're entirely expanded in-place by the compiler. Hence the difference.

  3. #3
    Join Date
    Aug 2007
    Posts
    858

    Re: "inline" and linking errors

    A function declared as inline automatically has internal linkage unless you specify otherwise.

    Inline functions never make it to the linker. They're entirely expanded in-place by the compiler. Hence the difference.
    Assuming, that is, that the compiler chooses to actually inline the function. It doesn't always do so.

  4. #4
    Join Date
    Jan 2009
    Posts
    19

    Re: "inline" and linking errors

    Would there ever be a case like this where I declare a function inline, but the compiler chooses it not to be, breaking the code? Is there a more robust way to implement this kind of template specialization across multiple object files?

  5. #5
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: "inline" and linking errors

    Switching debug on frequently de-inlines functions. The compiler often ignores "inline" on large functions, or for any of a number of reasons.

    It won't break the code, since the compiler knows what it's doing. Taking the "inline" off manually, however, is not the same as the compiler doing it, since the compiler does much more as part of the process (which is why it won't break - the compiler takes special steps).
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  6. #6
    Join Date
    Aug 2007
    Posts
    858

    Re: "inline" and linking errors

    Quote Originally Posted by jakevdp View Post
    Would there ever be a case like this where I declare a function inline, but the compiler chooses it not to be, breaking the code? Is there a more robust way to implement this kind of template specialization across multiple object files?
    If the compiler decides not to inline the function, it's basically transparent to you. It'll still have internal linkage so it won't "break".

  7. #7
    Join Date
    Feb 2005
    Location
    "The Capital"
    Posts
    5,306

    Re: "inline" and linking errors

    The error that you face is not specific to templates or specializations. You will face the same problem if you turned foo into a non-template function.

    C++ functions have external linkage hence they must be implemented in just one .cpp (implementation file). They can however be declared multiple times.

    When you provide the implementation in the header file (this is what forced you to see the problem when using template because you put the implementation in the header as well since 'export' doesn't work), and include it into multiple compilation units (consider: .C/.cpp files), you have multiple definitions and hence the linkage error.

    With inline functions, you provide the implementation in the header file so as to be visible to the compilation point where they are used. They become inline in the final executable or not is irrelevant. You just follow the rule to define the inline functions.

    A way to solve this would be to keep the specialization as inline or declare it as not an specialization but just overload foo function and declare it in the header and provide implementation in a seperate implementation file. You don't face such issues with regular templates (non-specializations) because the instantiation guarantees that there is just one copy of the function generated as and when needed.

  8. #8
    Join Date
    Nov 2008
    Location
    England
    Posts
    748

    Re: "inline" and linking errors

    Quote Originally Posted by Lindley View Post
    Inline functions never make it to the linker. They're entirely expanded in-place by the compiler. Hence the difference.
    Not entirely true at all.

    Read this. Herb Sutter discussing inline.
    Get Microsoft Visual C++ Express here or CodeBlocks here.
    Get STLFilt here to radically improve error messages when using the STL.
    Get these two can't live without C++ libraries, BOOST here and Loki here.
    Check your code with the Comeau Compiler and FlexeLint for standards compliance and some subtle errors.
    Always use [code] code tags [/code] to make code legible and preserve indentation.
    Do not ask for help writing destructive software such as viruses, gamehacks, keyloggers and the suchlike.

  9. #9
    Join Date
    Jan 2009
    Posts
    19

    Re: "inline" and linking errors

    Quote Originally Posted by exterminator View Post
    A way to solve this would be to keep the specialization as inline or declare it as not an specialization but just overload foo function and declare it in the header and provide implementation in a seperate implementation file.
    Thank you for the response, that helps a lot. This little piece right here is not entirely clear to me. Would you mind elaborating a bit? What do you mean by overloading, rather than specializing? Thanks
    Jake

  10. #10
    Join Date
    Feb 2005
    Location
    "The Capital"
    Posts
    5,306

    Re: "inline" and linking errors

    Quote Originally Posted by jakevdp View Post
    This little piece right here is not entirely clear to me. Would you mind elaborating a bit? What do you mean by overloading, rather than specializing?
    The way you normally overload functions. Without the template<>. Just another non-template function with the same name and your choice of argument type (double in the example above) or number (not the case here).

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured