11

The following code segment compiles with no problems, even though foo is defined inline but not declared as such, and bar is declared inline but not defined as such.

int foo();
inline int foo() { return 3; }

inline int bar();
int bar() { return 4; }

inline int foobar();
inline int foobar() { return 5; }

int main(){
    // ...
}

My first question: does the compiler read foo as inline or not? What about bar? Is this specified by the C++ standard?

My second question: Which one of these is the best practice in declaring and defining inline functions? Is it foo? bar? or foobar? Why?


inb4 I read some other posts related to this but none of them answer my question directly.

This answer seems to suggest that foo is inline, but says nothing about bar. It also doesn't explain why foo is preferred over the others. This answer talks about when I should use inline functions. That's not my concern: I've already decided to use inline functions. My question (question 2, to be precise) is whether I should declare it as such, define it as such, or both, and why one of the conventions is better style than the rest. This question seems to be closer to my concern but nobody answered it.

HazySmoke
  • 263
  • 1
  • 8
  • I think both break the One Definition Rule: http://en.cppreference.com/w/cpp/language/definition – Richard Critten Jun 27 '17 at 19:35
  • A function as simple as `{ return 3; }` will almost certainly be inlined, regardless of how you define/declare it. – James Curran Jun 27 '17 at 19:35
  • 2
    @James It's a simple code snippet to demonstrate my question. Posting a "realistic" function would distract from my main point. – HazySmoke Jun 27 '17 at 19:36
  • 1
    @Richard there are three functions defined: foo, bar, and foobar. Which two are breaking the one definition rule? (And how is it? I'm only defining the functions once.) Also please see my original questions. (first question and second question) – HazySmoke Jun 27 '17 at 19:39
  • 1
    @RichardCritten - NO. Each function is defined only once. They have a possibly conflicting declaration, but only one definition. – James Curran Jun 27 '17 at 19:39
  • @πάντα ῥεῖ The duplicate question you suggested does not answer my concern. Again, as I *explained* in my question. I'm NOT concerned with whether or not to inline my function. I'm concerned with WHICH ONE is BETTER STYLE, and how does the compiler read foo, bar, and foobar. – HazySmoke Jun 27 '17 at 19:45
  • afaik it has to be on the declaration, seems like your compiler cares so little about the hint you are giving that it doesnt even care whether you put the `inline` on the definition or declaration – 463035818_is_not_an_ai Jun 27 '17 at 19:47
  • @HazySmoke Someone else already reopened your question. Now it's prone to be _off--topic_ being opinion based. Good luck with this. – πάντα ῥεῖ Jun 27 '17 at 19:47
  • @πάντα ῥεῖ I don't see why discussion about advantages/disvantages of different coding styles has to be opinion based. Surely there's one that I've ought to use for my coding endeavours. (Besides that's only question 2. Question 1 is fact based) Therefore I believe that this is a legit question. – HazySmoke Jun 27 '17 at 19:50
  • My 1st commend is wrong: Referring to the current draft: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf [page 158 - 10.1.1 Storage class specifiers 6.] `foo` and `bar` are `inline` with external linkage, `foobar` is just `inline`. – Richard Critten Jun 27 '17 at 19:55
  • Useful explanations [here](https://stackoverflow.com/questions/1759300/when-should-i-write-the-keyword-inline-for-a-function-method) – Ripi2 Jun 27 '17 at 20:23

2 Answers2

2

True for member functions, and not explicitly-defined for non-member functions (I believe)

See §10.1.6 in ISO C++ std.

The inline specifier can be applied only to the declaration or definition of a variable or function

and

A function declaration (11.3.5, 12.2.1, 14.3) with an inline specifier declares an inline function.

It doesn't explictly state what will happen if an inline specifier only modifies the definition of a function.

What we can be sure of is that such member functions are guaranteed to be marked as inline (thanks to James Curran).

See §12.2.1.

An inline member function (whether static or non-static) may also be defined outside of its class definition provided either its declaration in the class definition or its definition outside of the class definition declares the function as inline or constexpr.

All three functions in GCC and non-member circumstance

As in GCC -O1 C++ mode, every function mentioned are inlined.

Code:

#include "stdio.h"

int foo();
inline int foo() {int i; for(i=0;i<100000;i++); return i+3; }

inline int bar();
int bar() {int i; for(i=0;i<100000;i++); return i+4; }

inline int foobar();
inline int foobar() {int i; for(i=0;i<100000;i++); return i+5; }

int foobar2();
int foobar2() {int i; for(i=0;i<100000;i++); return i+6; }

int main(){
    int a,b,c,d;
    a=foo();
    b=bar();
    c=foobar();
    d=foobar2();
    printf("%d %d %d %d", a, b, c, d);
}

Disassembly: IDA

We can see only foobar2 is called.

As in -O2 and -O3, inline doesn't matter so much. The compiler will decide by itself (in the case above, all 4 functions are inlined).

Keyu Gan
  • 711
  • 5
  • 17
  • OK, good to know. It seems from your example that gcc inlines all 3. – HazySmoke Jun 27 '17 at 20:01
  • 2
    Your answer is mostly useless. It is not interesting to know what is inlined by particular compiler with a particular set of options. The answer should contain quotes from the standard which explain the difference between all these declaration/definition pairs. – Edgar Rokjān Jun 27 '17 at 20:08
  • @EdgarRokyan thanks. I added related information from the standard. – Keyu Gan Jun 27 '17 at 20:25
  • No function is "*guaranteed inlined.*" The best you can do is "guaranteed to be marked as available for inlining". The compiler, will make the final decision. – James Curran Jun 27 '17 at 20:28
1

(NOTE: I reopened this question, as this is NOT a duplicate of the cited older question. That question involved design; this is about syntax).

Now, referring to the question cited by the OP in his question about inline in definition and declaration, the answer states that if the declaration is in a header file, then it was have the "inline" ("bar style"), because other source files using that header will try to link to it as if it were a non-inlined function and file.

Personally, I'd use

 inline int foobar() { return 5; }

in the header file without a separate declaration. (I always feel that if it's too big to be in the header, then it's too big to be inlined.)

TriskalJM
  • 2,393
  • 1
  • 19
  • 20
James Curran
  • 101,701
  • 37
  • 181
  • 258
  • Well, good point. I'd probably do that as well. It's just that I've seen places where people declare member functions as non-inline and later define them (in the header file) as inline, which makes me want to clear up this piece of syntax detail. – HazySmoke Jun 27 '17 at 20:01
  • @HazySmoke Member functions are inline when defined in class body by default, as is required in C++ standards. – Keyu Gan Jun 27 '17 at 20:03
  • @Keyu Gan I meant like it's declared normally in the class. And then *outside* the class body, it's defined as inline. And it's defined in the header file. – HazySmoke Jun 27 '17 at 20:04