Go Down

Topic: C vs C++ (Read 1 time) previous topic - next topic

Andreas J.

Hi all,

this may sound like a stupid question, but it took me half the night...

What's the difference between C and C++ wehn creating an arduino library?

Background: I do have quite a big library written in C, that I wanted to use for Arduino projects.
As the core libraries themselves are a mixture of C and C++ I did not expect too much trouble in creating a lib out of my dozen of *.c files.
However, I could not get it to work until out of desperation I started a trivial example and played around with it for a while.
Here I discovered, that it works, if I simply rename *.c to *.cpp

I did look at the verbose compiler output, but I can't find any clue, besides that avr-g++ gets called instead of avr-gcc.
How does that influence the corresponding *.o?
How does the core library handle this?

BTW: Of course did I rename all my *.cc to *.cpp and coud get the project to work, but I still want to understand it!?

Best Regards,

Andreas


Groove

Google 'C++ name mangling'.
It is all about how C++ manages polymorphism.
Per Arduino ad Astra

PaulS

C++ allows you do this:
Code: [Select]
class stuff
{
  int add(int, int);
  float add(float, float);
  char *add(char *, char *);
};

How can there be three different functions with the same name?

The answer is that there aren't really 3 functions with the same name. C++ compilers use a process called name mangling to actually create 3 different function names, based on the function name and the argument types.

When the stuff::add() method is called, there are arguments supplied. The C++ compiler uses the supplied argument types, and name mangling again, to select the correct function to be executed.

So, when a C++ program makes a call to a function defined in a header file, the C++ compiler mangles the names in the header file, too, to create the name of the function to be called.

When the code that goes with the header file is in a .c file, the C compiler is invoked to create the object file.

When the linker runs, the name that the C++ function wants to use (the mangled one) is NOT in the object file created by the C compiler.

When you renamed the file to .cpp, the C++ compiler processed it, mangled the names, and created the object file.

Then, when  the linker looked in the object file, the name it was looking for was there.

You can add information to the header file to tell the C++ compiler that the C compiler will be compiling the source code, so that the C++ compiler does not perform name mangling on the function names.

[glow]extern "C" [/glow]void someFunction(/*some arguments*/);

The extern "C" prefix may cause issues trying to call the function from C code, so the prefix can be optionally provided:

#ifdef __cplusplus
extern "C" {
#endif
void someFunction(/*some arguments*/);
int anIntFunc(int anArgument);
#ifdef __cplusplus
}
#endif

The extern "C" prefix can be applied to one function as in the first example, or to multiple functions, by using { and }, as in the second example.

So, now you know more than you probably ever want to know about multi-language application development.

Andreas J.

Hi PaulS and Groove,

thank you very much for your answers. This was the enlightement I was looking for.

Happy New Year

Andreas

Go Up