Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

c

inline

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.

like image 468
dragonroot Avatar asked Nov 08 '13 11:11

dragonroot


People also ask

Can inline function be defined in C file?

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.

Is it compulsory to declare function before its calling in C?

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.

Can we call a function without declaring it in C?

A compiler is required to complain if you call a function without declaring it first.

When might a compiler choose not to inline a function declared as inline?

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.


2 Answers

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.)

like image 160
leewz Avatar answered Sep 29 '22 06:09

leewz


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.

like image 45
M.M Avatar answered Sep 29 '22 05:09

M.M