Is declaring the function and then defining it inline legal in C/C++?
Asked Answered
R

3

9

Is the following legal in C and/or C++?

void fn();

inline void fn()
{
  /*Do something here*/
}

What concerns me is that the first declaration looks like it implies that the function will be defined non-inline, but the following definition turns it into an inline after all.

If there's a difference between C and C++ in this case, it would be nice to know that difference, too.

Rightly answered 8/11, 2013 at 11:38 Comment(3)
C or C++? (inline is very different between the two.)Madelon
Well, my gcc compiles this both in c and c++ mode just fine. If there's a difference in handling this code example in c and c++, I would very much be interested in knowing that difference :) I've edited the question to reflect this.Rightly
Here is a good read on the differences.Direction
P
5

Yes. In fact, it's probably preferable. Source: http://www.parashift.com/c++-faq/inline-nonmember-fns.html

Rule of thumb: Declaration tells you how to call a function and use its return value. Definition says what happens when you call it. You can change a function to inline and back without modifying how you call it, so it makes sense that it's part of the definition. (Of course, what makes sense and what is true don't always match, so this is only a rule.)

Phane answered 8/11, 2013 at 12:5 Comment(1)
It would be preferable to quote the relevant text and provide the link as reference.Leveridge
L
4

In ISO C++ (non-member function)

It is OK only if the code actually appears in the header file as shown. It would be undefined behaviour (no diagnostic required) if the header file contains a non-inline declaration, but the inline definition does not appear in all translation units; even if the function is not called.

Reference: C++14 [dcl.fct.spec]/4 (note that a definition is also a declaration):

If a function with external linkage is declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required.

In ISO C++ (member function)

If the code appears inside a class definition, it is OK and the inline keyword is redundant, since function definitions that appear inside a class definition are implicitly inline.

If the class definition contained void fn(); and then there was an out-of-line definition inline void Class::fn() { , the behaviour is the same as for the non-member case.

In ISO C

C11 6.7.4/7:

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.

The existence of a non-inline declaration means that the later definition is not an inline definition, despite the fact that it has the inline keyword. So the definition is actually an external definition (i.e. same linkage properties as if it had not been marked inline).

Therefore, if this code appears in a header file included by two translation units it is undefined behaviour due to multiple external definitions; but if the prototype is in a header and the definition is in one translation unit which includes that header, it is OK.

Note: GNU C inline differs to ISO C inline. I am unsure of the defined behaviour of this code in GNU C.

Leveridge answered 19/11, 2017 at 22:15 Comment(0)
C
-1

An inline function is one for which the compiler copies the code from the function definition directly into the code of the calling function rather than creating a separate set of instructions in memory. Instead of transferring control to and from the function code segment, a modified copy of the function body may be substituted directly for the function call. In this way, the performance overhead of a function call is avoided.

C Any function, with the exception of main, can be declared or defined as inline with the inline function specifier. Static local variables are not allowed to be defined within the body of an inline function.

C++ functions implemented inside of a class declaration are automatically defined inline. Regular C++ functions and member functions declared outside of a class declaration, with the exception of main, can be declared or defined as inline with the inline function specifier. Static locals and string literals defined within the body of an inline function are treated as the same object across translation units.

The inline function specifier

Conclusion

C++

Classes: Both your functions have the same prototype essentially. However since the first function will be embedded in a class, it is in a different scope than the defined inline function. Thus it will be fine.

Non Classes: If you do not embed the non inline function in a class it will be treated as a redefinition error and will give a compile error. Because it expects overloading but the prototypes are the same.

C

The same hold for C as the C++ variant for non Classes. Thus if you define it like you did in your question in a .c file the compiler will throw you a redefinition error. Like:

redefinition of 'fn 

and/or a note:

previous definition of 'fn' was here
Candiecandied answered 8/11, 2013 at 12:0 Comment(2)
If you're going to copy and paste an answer from someone else's website, you should cite the source.Utrecht
Oh didn't that go in quotes, crap sorryCandiecandied

© 2022 - 2024 — McMap. All rights reserved.