I'm trying to create C funciton wrappers for C++ and my goal is to make them inline. All the solutions on the internet say that when making an inline function in a library, just put the function definition in the header file. This won't work in this case though, since the functions contain code that will only compile in C++.
This example demonstrates the situation:
// box_c.cpp
#include "box.h"
extern "C" Square *new_Square(int width, int height){
return new Square(width, height);
}
// box_c.h
void *new_Square(int width, int height);
// main.c
#include "box_c.h"
int main(void){
void *s = new_Square(5, 5);
}
Wold it be possible to make new_Square inline in this case? (The wrapper is a static library).
Inlining means the compiler of the source where it is inlined needs to understand it on some level. C compilers don't understand C++ new. You can't do this. Leave it non-inlined, so a compiled version of the code can be linked without the compiler needing to understand C++ natively.
If the code (both library and final executable) is compiled with LTO enabled, it's possible the linker might inline the code at that point, but there are no guarantees there.
Obviously in general you cannot inline C++ code inside C code, they are two different languages.
So, either
force the explicit instantiation of the C++ function in the compiled library,
ensure that the C++ function is code-compatible with C and leave it in the header file as inline.
Related
My Problem is that I want to call some template function in C.
Therefore, I have declared an extern "C" function as a wrapper function, which calls this template function.
I know, that I need to compile the wrapper function, with the c++ compiler and then I get an object file, which I can link against a normal c-program.
The problem is, that I have written a header only C++ library, which I want to use in C, but in C I can't make the library header only anymore, once I need to link the C-program against the wrapper function.
So does there exist any way of generating a header only c-library, which calls the c++ template function? This method should work in GCC and it is absolutely no problem, if it is nonstandard, requires several pragmas, cli-parameters or something else.
I think, a possible solution would be to call gcc in C-mode on a file, where on a particular line, a switch from C to C++ inside the header file is possible. This C++ switch does the actual template call and than a switch back to the C-compiler is performed. Does some method exist?
e.g. like this:
#include <iostream>
#define SWITCH_TO_CPP_COMPILER() /*TODO: is this possible?*/
#define SWITCH_BACK_TO_C_COMPILER() /*TODO: is this possible?*/
#ifdef __cplusplus
extern "C" {
#endif
inline bool wrapper();
#ifdef __cplusplus
}
#endif
SWITCH_TO_CPP_COMPILER();
template<bool tmp>
constexpr bool template_func() noexcept {
return tmp;
}
inline bool wrapper() {
return template_func<true>();
}
SWITCH_BACK_TO_C_COMPILER()
#include <stdio.h>
int main() {
printf("%d\n", wrapper());
}
I have already looked at several questions, but they do not answer it:
C Wrapper for C++: How to deal with C++ templates?
how to write c wrapper around c++ code to expose class methods
Create a C wrapper around a C++ library that can be linked by a C linker
C wrapper around C++ library without unnecessary header files
The whole point of the C wrapper is to have the C++ compiler generate an object module for the instantiated template and the wrapper, and letting the C compiler be blissfully unaware of anything but the wrapper, known/invoked thorough an extern function declaration.
This thing cannot be header-only: a header is brutally included in the file that uses it, and that file is going to be processed by a C compiler, which then would have to be able to parse/instantiate the C++ template besides the wrapper function, and this is obviously not possible. Parsing C++ is already complex as it is, requiring to switch to a different language in mid-air is completely bonkers.
If you want to use your library into a "C proper" program you have to have an extra TU compiled by a C++ compiler. Otherwise, since however you think about this you need some C++ compiler being able to compile your template, just compile everything in C++ and, if you prefer, just use the C subset for the rest of the files.
You already have a dependency from a C++ compiler and most probably from the C++ standard library, so this isn't going to change much besides compilation speed in the grand scheme of things.
This in mind what Matteo wrote in his answer:
Convinced that what OP wants is impossible, I tried to find a substantive argument.
I compared the "Phases of translation" for C and C++.
The first phases concerning pre-processing look quite similar but starting with phase 7 (compilation) it becomes quite different.
I hardly doubt that any compiler can switch from C to C++ and back in the mid of a translation unit (if it is standard conform).
Is there any way to call a C++ function from a C source file , without using extern "C" prior to the function declaration in the C++ file e.g :
//C++ source file
extern "C" void func_name();
void func_name()
{
....
}
The only way to not use extern "C" directly is to manually determine the mangled name and call that from C; which is essentially just doing extern "C" but manually. There's no point or purpose or alternative method with any merit whatsoever.
I'm not aware of any combination of C and C++ compilers that provide an officially supported way to do this. You're supposed to use extern "C" in the C++-side header files.
However, perhaps you have to anyway; I can think of several reasons other than homework, such as when you've got a third-party C++ library with an interface that could be invoked from C but the developers neglected to put extern "C" in the headers, and you can't recompile it.
There is usually an unofficial way to do it: you have to find out the mangled name of the C++ function, and any hidden parameters that it has (this is almost always treated as a hidden first parameter, and there may be others). You then write a declaration on the C side using the mangled name and the full parameter list.
Here is a very simple example that will work with GCC on most operating systems and CPUs:
/* file1.cpp */
#include <cstdio>
void foo()
{
puts("hello from foo");
}
/* file2.c */
#include <stdio.h>
extern void _Z3foov(void);
int main(void)
{
puts("hello from main");
_Z3foov();
return 0;
}
Because this is homework I am not going to give you a more complicated example, but I am going to point you at the so-called "Itanium C++ ABI", which specifies how the mangling and the hidden parameters work with GCC and Clang on most operating systems and CPUs. (Be aware that MSVC uses a completely different, undocumented, scheme. I have heard rumors that Clang can optionally use MSVC's scheme now but I'm not sure I believe it, considering how gargantuan a reverse-engineering job it would have been. ;-)
(In case you're wondering, mangled names are how function and operator overloading are implemented in the linker. If my file1.cpp had defined both void foo(void) and void foo(int), that would have produced an object file exporting the mangled names _Z3foov and _Z3fooi.)
You could write a separate translation unit, let's say mycppunit.cpp containing your void func_name() implementation without any extern "C" declarations. Compile this translation unit into a binary using a C++ compiler, yielding, for example, a mycppunit.o binary; then, use a command line tool like nm to find out how the function name has been mangled: For example:
nm mycppunit.o | grep func_name
would give something like
000000010006a920 T __Z9func_namev
Then you may assume that there will be a function void _Z9func_namev() available, and you can write in a translation unit, e.g. `my_c_program.c, the following:
void _Z9func_namev();
int main() {
_Z9func_namev();
}
Compiling this with a C compiler and linking it together with the mycppunit.o will give the desired result.
Hope it is what you are looking for.
Lately, some of my CPP tutorials have used function prototypes . I understand you must initialize the function, but what is the overall use of it? Couldn't you use just as well write the entire function before main() instead of defining a prototype?
int returnValue(void);
int main()
{
std::cout << returnValue() << std::endl;
return 0;
}
int returnValue(void)
{
return 10;
}
Couldn't you use just as well write the entire function before main() instead of defining a prototype?
I can think of the following cases where you cannot.
Functions used in multiple files
If a function is used in multiple source (.cpp) files, you can define the function only in one source file. You have to declare it in the remaining source files. For convenience and to avoid errors, such declarations are put in header files. The header files are then #included by the source files.
Mutually recursive functions
If foo calls bar and bar calls foo, you cannot implement them without providing a declaration of at least one of the functions.
As a matter of good practice, it's better to declare both functions first. Then you can implement them in any order.
One important usage case is when you separate your implementation from the declarations. In other words, you declare your functions/classes etc in a header file, and define (i.e. implement) them in cpp files. In this way, you can distribute your program with the implementation fully compiled in a shared or static library. In order to use a pre-compiled function you need to introduce it to your program via a declaration. Example:
a.h
void f();
a.cpp
void f(){/* implementation here */}
main.cpp
#include "a.h"
int main()
{
f();
}
Including "a.h" in main() is declaring the function. Once you compile the a.cpp once, you don't need it's source any more, the program will run provided you have at least access to the object file, but in order for the linker to find the function f() you need to declare it.
If one doesn’t specify the function prototype, the behavior is specific to C standard (either C90 or C99) that the compilers implement. Up to C90 standard, C compilers assumed the return type of the omitted function prototype as int. And this assumption at compiler side may lead to unspecified program behavior.
Later C99 standard specified that compilers can no longer assume return type as int. Therefore, C99 became more restrict in type checking of function prototype. But to make C99 standard backward compatible, in practice, compilers throw the warning saying that the return type is assumed as int. But they go ahead with compilation. Thus, it becomes the responsibility of programmers to make sure that the assumed function prototype and the actual function type matches.
To avoid all this implementation specifics of C standards, it is best to have function prototype.
I want to use this C++ Library in C-Code (and compile the code with gcc):
https://github.com/fairlight1337/libcflie
To do that I added Wrapper functions to CCrazyflie.h, CCrazyflie.cpp, CCrazyRadio.h and CCrazyRadio.cpp (all functions I want to use are in those Files):
Added to CCrazyRadio.h:
extern "C"
{
CCrazyRadio* newCCrazyRadio(string strRadioID);
void deleteCCrazyRadio(CCrazyRadio* cr);
int CCrazyRadio_startRadio(CCrazyRadio* cr);
}
Added to CCrazyRadio.cpp:
extern "C"
{
CCrazyRadio* newCCrazyRadio(string strRadioID) {return new CCrazyRadio(strRadioID);}
void deleteCCrazyRadio(CCrazyRadio* cr) {delete cr;}
int CCrazyRadio_startRadio(CCrazyRadio* cr) {if(cr->startRadio()) return 1; else return 0;}
}
I did the same thing for the functions in CCrazyflie.h and CCrazyflie.cpp.
I can use the wrappers in C-code and they work when compiled with g++, but when compiling with gcc the compiler complains that it doesn't know iostream (included in CCrazyflie.h and CCrazyRadio.h which are both included in my C-code).
Am I doing this right? How can I make gcc find iostream (and the other C++ libraries that are included)?
If needed I would be happy to show you more of the code, I just tried to keep the post short.
Thanks in advance for any help!
Regards,
Daniel
The problem is not the linker as some have suggested, or that the wrappers need to be compiled with a C++ compiler (although they do).
The issue is that the C file includes the header that defines the wrappers, and the wrapper functions take types that the C language doesn't have - eg string. The extern statement tells the C++ compiler not to mangle the names, but doesn't magically make anything inside legal C.
So, your wrapper functions need to be defined to take C types, so your
CCrazyRadio* newCCrazyRadio(string strRadioID);
becomes something like
CCrazyRadio* newCCrazyRadio(char * radioId);
And internally to newCCrazyRadio you can construct a string to hold your radioID, if needed. If CCrazyRadio is a class, you will still have troubles though. So, if this is just being returned as some sort of handle, you could perhaps replace with a void*
You still need the extern 'C'.
You will also need to ensure that the header containing the wrapper functions ONLY includes C header files. Even if gcc (in C mode) can find them, they will not contain valid C code. This means it cannot include iostream etc.
One further thing, I recall that C doesnt understand the extern C syntax, so you may need to wrap that with a conditional compiliation block eg (you will need to check the syntax your self)
#ifdef _CPLUSPLUS_ // Check this bit
extern 'C'
{
#endif
//Put your prototype wrappers here
#ifdef _CPLUSPLUS
}
#endif
This basically means that only the C++ compiler will see the extern C directive.
I have a question about extending already used headers, sources and objects.
Before understanding what I mean you just have to accept that I want to use this design:
In a project of mine, I use only function declarations in a header, and for each definition I use a seperate source file, which will compile to a seperate object file.
Let's say I have a very simple class called List in directory "src".
The header could look like:
File: src/List.hpp
//[guard]
//[includes]
class List {
void add(int value);
void remove(int index);
void clear();
};
Now the three functions would have seperate files:
File: src/List/add.cpp
void List::add(int value) {
// Do something
}
imagine the other 2.
These will be compiled at a certain moment, and the header file will be used in other compiled classes.
Let's assume that another class called ABC uses the header file of List.
For each function in the class ABC, a object file is generated.
Now we want to adjust the header of List, we don't want to change a function, we only want to add a function:
File: src/List.hpp
//[guard]
//[includes]
class List {
void add(int value);
int find(int value);
void remove(int index);
void clear();
};
So another source file and object file is being generate, it's called in this example: src/List/find.cpp and src/List/find.o
Now my question, is this a legal way to use headers, sources and objects?
Would this generate problems, or isn't this possible at all?
Also, is the class called List in class ABC still the same as the newly created class called List?
Your design seems workable. However, I won't recommend it. And you didn't mention templates or standard containers.
My feeling is that
it is practically important (for efficiency reasons) to have a lot of (usually small) inline functions, notably inlined member functions (like getters, setters, etc...), often contained in their class Class { .... } definition.
hence, some of the member functions should be inline, either inside the class like
class Foo {
int _x;
Foo(int x) : _x(x) {};
~Foo() { _x=0; };
int f(int d) const { return _x + d; };
}
then all of constructor Foo::Foo(int), destructor Foo::~Foo and member function int Foo::f(int) are inlined
or after the class (usually easier for machine generated code) like
class Foo {
int _x;
inline Foo(int x);
inline ~Foo();
inline int f(int d) const;
};
Foo::Foo(int x) { _x = x; };
Foo::~Foo() { _x = 0; };
int Foo::f(int d) const { return _x+d; };
In both cases you need inlining (or perhaps Link Time Optimization e.g. gcc -flto -O for compiling & linking) for efficiency reasons.
The compiler can only inline functions when it knows their definition (their body).
then, every time you #include some class definition. you need to somehow get that inline function definition compiled. Either you put it in the same header, or that header should itself #include some other file (providing the definition of inlined functions)
In general, especially when using standard C++ library (and using standard containers, so e.g. #include <vector>) you'll get a lot of system headers (indirectly included). In practice, you don't want very small implementation file (i.e. having a few dozen lines of your source code per file is impractical).
Likewise, existing C++ framework libraries pull a lot of (indirect) headers (e.g. #include <QtGui> brings a big lot of code).
I suggest having C++ source files (either *.hh or *.cc) of a thousand lines each at least.
Look at the size of the preprocessed code, e.g. with g++ -H -C -E ... you'll be scared in practice: even when compiling a small C++ file of a few dozen lines of your source code, you'll have thousands of preprocessed source lines.
Hence my advice of thousand lines source file: any smaller file using the C++ standard library or some C++ framework library (Boost, Qt) is pulling a lot of source lines from indirectly included files.
See also this answer, why Google (with D.Novillo) tries hard to add preparsed headers to GCC, why LLVM/Clang (with C.Latner) wants modules in C and C++. And why Ocaml, Rust, Go, ... have modules...
You could also look at the GIMPLE representation generated by GCC, either using the MELT probe (MELT is a domain specific language to extend GCC, the probe is a simple graphical interface to inspect some internal representations of GCC like Gimple), or using -fdump-tree-all option to GCC (be careful: that option produces hundreds of dump files). You may also pass -ftime-report to GCC to understand a bit more where it is passing its time when compiling your C++ code.
For machine generated C++ code I recommend even more generating less files, but make them bigger. Generating thousands of small C++ files of a few dozen lines each is inefficient (making the total build time too long): the compiler will spend a lot of time parsing the same #include-d system headers again and again, and instantiating the same templated types (e.g. when using standard containers) a lot of times.
Remember that C++ permits to have several classes per source file (contrarily to Java (except inner classes)).
Also, if all of your C++ code is generated, you don't really need to generate header files (or you might generate one single big *.hh) because your generator should know which classes & functions are really used in each generated *.cc and could generate in that file only those useful declarations and inlined functions definitions.
P.S.: Notice that inline (like register) is just a (useful) hint to the compiler. It may avoid inlining a function marked inline (even implicitly, when inside class definition). It may also inline some functions not marked inline. However, a compiler needs to know the body of a function to inline it.
I believe whether a function is inlined is determined by the compilator (see question How will i know whether inline function is actually replaced at the place where it is called or not?). To inline a function (though this does not necessarily mean the function will absolutely be inlined at compilation) you should either define the function inside its class, or use the command "inline" before defining your function outside of it, in the header. For example :
inline int Foo::f(int d) const { return _x+d; };
Yes, that works just fine. It's how static libraries are implemented, because that makes it easier for the linker to not pull in things that aren't used.