cukier9a7b5 cukier9a7b5 - 9 days ago 5
C Question

extern inline function was referenced but not defined

I have a function (lets call it

void foo(void) {}
) that I wish to be inline.But I defined it inside .cpp file.

I can not move the function to the header because it is using other functions from .cpp.




EDIT:

code below just like real one is not using c++ features. I can clearly add:

#ifdef __cplusplus
extern "C"
#endif


If i would like to convert code below to c99 i need only to change my project properties (or makefile if you like) NOT THE CODE. I am asking also about c++ because meaby it can solve my problem while c99 can not.

therefore C and C++ tags in my question are justified. the code is portable

see: When to use extern "C" in C++?




EDIT #2

Ok i understand that i must put
foo()
definition inside header file. How can I call
func_a()
and
func_b()
from
foo()
without moving them to the header file? Is there any workaround?




Example

file.c / .cpp:

int func_a (int a, int b, int c) {/*...*/};
double func_b (double a, double b, double c) {/*...*/};

void foo (int a, double b) { // unction definition
//...
int myInt = func_a(a, 2, 3);
//...
double myDouble = func_b(1.5f, b, 3.5f);
//...
}


file.h:

// Something before.

void foo (int a, double b); // function declaration

// Something after.





I want to point out:


  • I am working with Visual Studio 2015.

  • I am writing relatively big project ( ~ 7000 Lines Of Code ). It is simulation of physical system.

  • file.h
    is included to many other compilation units.

  • foo(int, double)
    is small and it calls other functions from
    file.cpp

  • I want to make
    foo(int, double)
    inline because of optimization reasons ( I will end up using
    __forceinline__
    )

  • I am calling
    foo()
    many, many times across my program. Also it is used inside few while loops ( 100k + iterations each ) so it is expansive to let this symbol
    foo()
    be not inline.

  • I am sick of header-only libraries.






I tried to:

file.c / .cpp:

extern inline
void foo (int a, double b) {\*...*\}; // Definition


file.h:

extern inline
void foo (int a, double b); // Declaration


but I keep getting an warning:


warning : extern inline function "foo" was referenced but not defined


And i do not understand why i am getting this warning.




Is there any way to:


  • keep definition of
    foo()
    inside my .cpp file ? But still make it inline

  • move
    foo()
    to the
    file.h
    , keep
    func_a()
    and
    func_b()
    inside
    file.cpp
    , but make
    func_a()
    and
    func_b()
    symbols "visible" to the
    foo()
    ( ! and only to the
    foo()
    ! ) from
    file.cpp

  • any other workaround?





Sory I am still learning cpp and I dont know if my question is clear, or is it even possible to make function inline from .cpp file.

Answer

In C++, the inline keyword means this:

  • The function's body must be present in every source file which uses that function.
  • The function's "bodies" in all source files must be token-by-token and entity-by-entity identical.
  • The compiler&linker must make sure they're fine with the function having these "multiple bodies"

That's all that it does. In practice, this means that it enables and forces you to put the function body into a header file.

The keyword itself has nothing to do with function inlining, per se. It's just that if the compiler wants to be able to inline the function's body, it must have access to it when compiling the calling code; in other words, the function's body must be in the same source file or in a header file included by that source file.

If you want to enable the compiler to inline the function in all call sites, and these call sites happen in more than one source file, you have to put the function into a header file (and mark it as inline).

On the other hand, it is also possible for the linker to do inlining, called Link-Time Code Generation or Whole Program Optimisation or something similar (depending on your toolchain's vendor). Enabling this will

  1. extend your build times, and
  2. allow the linker to inline functions into call sites across source files

So to inline the function, you have two options. Either put the function into a header file, or enable and rely on link-time optimisation to inline it for you.


In your particular case, to use __forceinline__, you'll have define foo in a header file. This requires the definition of foo to see declarations of func_a and func_b. To prevent namespace polution, you can declare these functions within the scope of foo:

inline void foo(int a, double b) { // function definition
    int func_a(int, int, int);
    double func_b(double, double, double);

    //...
    int myInt = func_a(a, 2, 3);
    //...
    double myDouble = func_b(1.5f, b, 3.5f);
    //...
}
Comments