dsyleixa123 wrote: ↑Fri Sep 25, 2020 8:40 pm
thank you all for your efforts, but my english is too poor to understand what "mangling" means or does for which purpose exactly and why this collides with my (actuall, Gordon's) legal C lib code, and all he foos don't make it more clear, tbh...
ok, let it be.
But apart from mangling, can anyone please explain me what this obfuscated weird block means or does?
Code: Select all
#ifdef __cplusplus
extern "C" {
#endif
extern int ads1115Setup (int pinBase, int i2cAddress) ;
#ifdef __cplusplus
}
#endif
I mean, line by line, and which lines are alligned to which other lines to sort of combined "blocks" - I don't recognize any valid code syntax in there, it all looks totally cofusing and senseless, just if one rolls letters by dices and places them unsorted on Scrabble fields...
Here goes...
#ifdef and
#endif are standard C-Pre-Processor directives, if the identifier is defined then the code in the block will be parsed by the compiler. If the identifier isn't defined then the code in the block will be ignored, think of it like selectively commenting out code.
Code: Select all
#ifdef __cplusplus
extern "C" {
#endif
The C++ compiler will implicitly define
__cplusplus so the line
extern "C" { will be parsed by the compiler.
The C compiler however will not define
__cpluscplus so that line will be not be parsed by the compiler.
Same goes for the other
#ifdef...#endif block, so effectively when compiled as C you just end up with one line,
Code: Select all
extern int ads1115Setup (int pinBase, int i2cAddress) ;
But when compiled as C++ you get three lines (I've added indentation to hopefully make it clearer),
Code: Select all
extern "C" {
extern int ads1115Setup (int pinBase, int i2cAddress) ;
}
What this tells the C++ compiler is that
- The function ads1115Setup will be linked as a C function and not as a C++ function (because it is in an extern "C" {...} block). This doesn't mean that the function is necessarily compiled with C, it just means that it will be called using C conventions rather than C++.
- It has external linkage (from the extern on the line declaring the function). Though functions at file scope have external linkage by default so you don't technically need this extern, only case I can think of where it matters is when using extern inline
C++ name mangling just means that C++ changes the names of functions by some means when generating object files. I'll use g++'s name mangling scheme, other compilers on other platforms may use an entirely different name mangling scheme, in fact they will do so unless their compiler generates object files that are meant to be directly compatible. Using this function declaration
The C compiler will generate a symbol named
add for the function and whenever you call the function it generates a call to
add.
The C++ compiler will instead generate a symbol named
_Z3addii for the function and whenever you call the function
add it actually calls the function
_Z3addii
Hopefully you can see that if the function is in an object file that was generated by a C compiler then trying to use that function from C++ wouldn't work because the name differs. This is why you have to tell C++ to use the C naming system for that function.
C++ uses name mangling because the language allows function overloading, simplistic example:
Code: Select all
#include <cstdio>
int add( int x, int y)
{
int z = x + y;
printf("integer add %d to %d to get %d\n", x, y, z);
return z;
}
float add( float x, float y)
{
float z = x + y;
printf("floating point add %f to %f to get %f\n", x, y, z);
return z;
}
int main(void)
{
int i = add( 1, 2 );
float f = add( 1.1, 2.2 );
}
If C++ didn't mangle function names then there would be a problem, there are two separate functions but both have the same name. With name mangling there isn't a problem because C++ changes the function names to
_Z3addii for the integer add() and to
_Z3addff for the float add().
You can't do this in C, nor can you in C++ if you declared both the functions with
extern "C". You can still overload a function in C++ when using
extern "C" so long as only one version is declared with C linkage.