2

I am trying to call an inline function defined in C from C++ code and I am getting an unresolved symbol error. Can I even do this?

In def.h:

#ifdef __cplusplus
extern "C" {
#endif

#include "types.h"


extern inline void foo();


#ifdef __cplusplus
}
#endif /* extern "C" */

In def.c:

inline void foo()
{
    some code
}

Elsewhere in c++ code:

void bar()
{
    foo();
}

And this is where I get an unresolved symbol error. Is there a way to make this compile? And if so, how will it work? Will the compiler replace the function call in my C++ code by the C definition? Eliminating functional calls is important as this is for an embedded environment.

Thank you.

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
user1337
  • 69
  • 1
  • 7
  • 2
    `inline` and `extern` seem an odd combination. – user4581301 May 26 '17 at 19:46
  • Possible duplicate of [extern inline](https://stackoverflow.com/questions/216510/extern-inline) – Siguza May 26 '17 at 19:47
  • Another related question: [What is the use of the `inline` keyword in C?](https://stackoverflow.com/questions/31108159/what-is-the-use-of-the-inline-keyword-in-c) – user7860670 May 26 '17 at 19:48
  • "I am trying to call an inline function defined in C from C++ code" - That's not possible. THe ionline function has always C++ semantics. `extern "C"` only specifies using the C ABI! You cannot compiler C code with a C+ compiler! If you want a C function, you have to use a seperate compilation unit compiled by a C compiler. – too honest for this site May 26 '17 at 19:53
  • @user4581301 Which would be the right combination for what I wish to do? – user1337 May 26 '17 at 19:54
  • @user4581301: It is correct in C. But not well known. But this is C++, not C. – too honest for this site May 26 '17 at 19:54
  • @Olaf Actually this is C, is it not? The inline function is defined in a part of my codebase in C. – user1337 May 26 '17 at 19:57
  • @Olaf knew it wasn't going to work in C++, never seen it in C. Been reading. Some interesting reading on why and how it came about. user1337 the killer here is when in C++, do as the C++ans do. C++ is the consumer of this function, so it needs to be visible in C++. – user4581301 May 26 '17 at 19:59
  • It will not be inlined anyway so just remove the inline keyword. – n. m. could be an AI May 26 '17 at 20:02
  • @n.m. Why wouldn't it be? – user1337 May 26 '17 at 20:04
  • Because there is no way for it in this universe to be inlined. In order to inline a call, the compiler needs to see the source of the called function. Last time I checked magic didn't work, so you need to put the function definition in the header for it to be visible. – n. m. could be an AI May 26 '17 at 20:08
  • Read my comment carefully again! It is **not** C! Note that the `inline` specifier is just a hint. Most modern compilers will igonore it anyway. Leave optimisations to the compiler unless you **know** you have a problem and identified the hot-spots by peoperly profiling. As @n.m. wrote: It is wrong already. You have to swap places for the "declaration" and the definition. – too honest for this site May 26 '17 at 20:11
  • @user4581301: See ^. I'm not sure if it is not correct in C++ either. – too honest for this site May 26 '17 at 20:15
  • @olaf I think you have me there. On rereading it looks like `inline extern` is only UB in C++ if you're stupid enough to allow it to be redefined. – user4581301 May 26 '17 at 21:49

2 Answers2

5

Most compilers generate code on source file level; to generate code, the compiler must "see" the source of all functions for which it needs to generate code. Unless you have LTO/LTGC, you have to make the source of all inline functions available in every file where they are called.

Try moving the source of the inlined function(s) into the corresponding header:

def.h:

#ifdef __cplusplus
extern "C" {
#endif

#include "types.h"

inline void foo()
{
   some code
}

#ifdef __cplusplus
}
#endif /* extern "C" */

def.c:

Remove foo() definition from this file (or remove this file).

Elsewhere in c++ code:

#include "def.h"

void bar()
{
    foo();
}
rustyx
  • 80,671
  • 25
  • 200
  • 267
0

The definition of the inlined C function should go into a header visible and included by your C++ code.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 1
    In a C++ header, it is not a C inline function. – too honest for this site May 26 '17 at 19:55
  • Is there no way to maintain a header/source file combination for the C code? This is necessary for me because I swap the source file in test scenarios. – user1337 May 26 '17 at 19:55
  • @user1337 As far as I know, no. An inline means that in the assembly code, there's no jump to where the function is. The function code is inserted directly. That means that the compiler must know what the code looks like. – klutt May 26 '17 at 20:04
  • @RustyX So my aforementioned test design is not feasible if I want to use an inline function? – user1337 May 26 '17 at 20:10