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.
Inline functions are static, i.e. visible only within translation unit where they are defined. One solution is to define, not declare, but define inline function in header file.
Actually, it is not required that a function be declared before use in C. If it encounters an attempt to call a function, the compiler will assume a variable argument list and that the function returns int.
A compiler is required to complain if you call a function without declaring it first.
The compiler can't inline a function if: The function or its caller is compiled with /Ob0 (the default option for debug builds). The function and the caller use different types of exception handling (C++ exception handling in one, structured exception handling in the other). The function has a variable argument list.
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.)
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.
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.
C11 6.7.4/7:
If all of the file scope declarations for a function in a translation unit include the
inline
function specifier withoutextern
, 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With