12

I'm not quite sure about this in the standards. Say I have three files like this:

foo.h

#include <iostream>

inline void foo();

void foo()
{
   std::cout << "Foo" << std::endl;
}

foo.cpp:

#include "foo.h"

void baz();

int main()
{
   baz();
   foo();
}

bar.cpp

#include "foo.h"

void baz()
{
   foo();
}

Now, the definition for foo will be compiled into both compilation units foo.o and bar.o. If I understand it correctly, having inlined functions will avoid linker collition. G++ compiled and links this just fine, but with clang++ 2.8 I get this error:

/tmp/cc-7RdmYP.o: In function `foo()':
bar.cpp:(.text+0x50): multiple definition of `foo()'
/tmp/cc-LW3id3.o:foo.cpp:(.text+0x50): first defined here
collect2: ld returned 1 exit status

It seems that clang++ does not see void foo() as an inlined function. It does however, work fine when I add inline to the definition as well.

Do I have to add inline to void foo() as well here to have it be seen as an inlined function, or is this a clang++ bug?

tenfour
  • 36,141
  • 15
  • 83
  • 142
Maister
  • 4,978
  • 1
  • 31
  • 34

4 Answers4

4

Odds are that your clang uses C99 inline semantics. In C99, if one of your functions doesn't use "inline" or does include "extern", then the definition is an "external definition", which can only appear once in the program. See inline in C99.

In C++, your program is fine. In Clang SVN, this bug has been fixed and your program should work fine.

Community
  • 1
  • 1
Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
2

C++0X draft N3225 says in 7.1.2 Function specifiers:

  • clause 2: A function declaration with an inline specifier declares an inline function
  • clause 4: An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case.

So, to me, it looks like gcc is right & clang wrong, but there's still a (slim) chance that things were (are?) different in C++03..

Eugen Constantin Dinca
  • 8,994
  • 2
  • 34
  • 51
  • 1
    C++03 wording is identical except that "odr-used" was simply "used". – aschepler Feb 07 '11 at 19:34
  • @Eugen: the clause 1 seems quite interesting too *Functions-specifiers can be used **only** in function declarations* (my emphasis). – Matthieu M. Feb 07 '11 at 19:45
  • I think Ben Voigt is correct here (didn't think about it when quoting initially). A definition is also a declaration. The standard says: `An object declaration, however, is also a definition unless it contains the extern specifier and has no initializer.` – sstn Feb 07 '11 at 19:49
  • @sstn: Oh, I see your point now. But a more applicable Standard quote (functions are not objects!) is 3.1p2: "A declaration is a *definition* unless it declares a function without specifying the function's body, ...." or is one of a few other exclusions. – aschepler Feb 07 '11 at 20:04
  • @MatthieuM.: Definitions are also declarations as the standard uses the terms. – Fred Nurk Feb 08 '11 at 21:58
  • @Fred: then, why precise **only** ? The same paragraph applies for `virtual` and `explicit`, and those cannot be tacked on "external" definitions but can be used for methods declared inline within the class. So I wonder if it means that `inline` should appear at the first appearance of the function (whether definition or declaration), thoughts ? – Matthieu M. Feb 09 '11 at 07:15
  • @MatthieuM.: You must include "inline" before (or when) the function is defined if the function is ever declared as inline (excepting functions which are implicitly inline), but this doesn't have to be before the function is first called. – Fred Nurk Feb 09 '11 at 07:59
1

I believe that the intention of the standard has always been to allow a function to be made inline by having at least one declaration including the inline specifier but there was some uncertainty about when it was too late to add the first inline declaration. Was after the definition too late, or after the first call?

My reasoning for this is two fold, first the examples in 7.1.1, although non-normative and principally about storage class specifiers, suggest that inline isn't required on every declaration.

Secondly this defect report DR 317 from 2001 (voted in in 2005) which adds the "If the definition of a function appears in a translation unit before its first declaration as inline, the program is ill-formed." sentence. It is clear from the conversation that it was intented that inline isn't required on every declaration, specifically in the case of a member function defined explicitly inline but outside of the class body where the original declaration didn't have an explicit inline.

(That defect report also contains my mantra that inline is "more than a hint".)

Of course, as soon as a function with external linkage is an inline function due to one or more declarations including the inline specifier in one translation unit it must be declared inline in all translation units according to the rest of paragraph 7.1.2/4.

In the example in the question I believe that the intention is that foo is an inline function and that it is valid code although the normative text of the standard seems to me to be less clear than it could be.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
0

You have to use inline in both places.

Edward Strange
  • 40,307
  • 7
  • 73
  • 125
  • 4
    I can't find anywhere in the standard that requires this, and in fact, the standard specifically allows the case where a member function is declared `inline` at declaration, or definition, but not both (the function is `inline` in that case). – Ben Voigt Feb 07 '11 at 19:04
  • Maybe I am confusing things now, but the 1998 standard says "There can be more than one definition of [...], inline function with external linkage, [...] in a program provided that each definition appears in a different translation unit, [...]" (section 3.2, clause 5) – sstn Feb 07 '11 at 19:04
  • 7.1.2, clause 1 (1998 again...) says: "Function-specifiers can be used only in function declarations." – sstn Feb 07 '11 at 19:05
  • 2
    @sstn: it's definitely required to be marked inline in every translation unit, but the code in the question meets that requirement. Furthermore, a function definition is also a declaration. – Ben Voigt Feb 07 '11 at 19:05
  • @Ben: 7.1.2 clause 4 (n3225) *If the definition of a function appears in a translation unit before its first declaration as inline, the program is ill-formed*, so I would tend to agree with `@sstn` on this. – Matthieu M. Feb 07 '11 at 19:37
  • Are @sstn and @Matthieu arguing that `inline` can't appear on a free function definition? No, I must be misreading. What are they really saying? – aschepler Feb 07 '11 at 19:47
  • @aschepler: That's definitely legal - I made an isolated quotation from the standard. A definition is always a declaration, means it is allowed. – sstn Feb 07 '11 at 19:53