Go4Expert

Go4Expert (http://www.go4expert.com/)
-   C++ (http://www.go4expert.com/forums/cpp/)
-   -   Data handling between combined c - c++ code (http://www.go4expert.com/forums/data-handling-combined-c-cpp-code-t21473/)

mobz 23Mar2010 22:11

Data handling between combined c - c++ code
 
I was combining C and C++ codes for a certain application when I came across a peculiar feature. When I return a 'double' from cpp function called inside a c function the double values are not held. Here is a simple example:

File plus.cpp (cpp code)
PHP Code:

#include <stdio.h>
extern "C" double f();
double f()
{
   
double val=2.134;
   
printf("%lf\n",val);
  return 
val;


file main.c (c code)
PHP Code:

#include <stdio.h>
int main()
{
  
double w;
  
f();
  
printf("%lf\n",w);
  return 
0;


Compiling :
PHP Code:

gcc -c main.c
g
++ -c plus.cpp
g
++ -o test *.

Result:
PHP Code:

2.134000
-1752346657.000000 

The double value does not translate to the c code. Any ideas?

Thanks in advance

(PS: Things I cannot do -
1. Compiling C code using C++ compiler. The actual problem is a complex set of functions and libraries and this is not do able.
2. Convert C code to C++ or vice-versa. Same reason as above.
I am just trying to understand how the compilers work and/or reasons this happens.
)

xpi0t0s 24Mar2010 15:01

Re: Data handling between combined c - c++ code
 
f() is not defined in main.c. So the compiler assumes this is an int with no parameters, i.e. int f(); If you want something other than that then you have to prototype it (as you have done, unnecessarily, in plus.cpp).

You cannot compile C code with a C++ compiler because it is a different language. Use a C compiler. However you can integrate C code with C++ code, in the C++ code you have to declare the functions extern "C" to prevent name mangling.

C++ is a superset of C so converting C to C++ should be fairly easy. There are some significant differences though and you should read up on those before trying. It may be easier to compile the C code with a C compiler, and the C++ code with a C++ compiler, and link the resulting objects together.

Regarding the vice versa, no, obviously this is mostly impossible. C does not support all the object stuff you get in C++ and there are other major differences too. Don't even try.

xpi0t0s 24Mar2010 15:13

Re: Data handling between combined c - c++ code
 
There are probably other things you need to do to make the above code work. Is there any reason why your main is C and plus is C++? If it was the other way round this would be fairly easy to fix. The f() name will most likely be mangled and C won't be able to find it; there is no extern "C++" in C. extern "C" is a C++ specific feature for integrating C code into a C++ program.

What is Name Mangling I hear you cry. C++ supports function overloading, e.g.
Code:

double f(double x);
int f(int x);
char f(char x);

but the linker does not. So when the compiler compiles these to object code, it has to modify these names so that the linker does not throw "duplicate symbol" errors. So the first might become f$dbl, the second f$int, the third f$ch, in a hypothetical compiler where the name mangling works that way, and when some other C++ function calls f(double) it would look for f$dbl.

The reason this is a problem when integrating C code into C++ is that C does not support function overloading and knows nothing about name mangling. So the above three declarations will cause errors, and if you remove the 2nd and 3rd leaving double f(double) then this will be compiled (by a C compiler) into a function simply named f (actually _f but don't worry about the underscore). So a C++ program won't find this, because it's looking for f$dbl. So you have to prototype f in the C++ program as:
Code:

extern "C" {
  double f(double);
}

so that the C++ compiler knows f(double) exists and IS NOT called f$dbl.

But as you've declared f() in the C++ code and want to call it in the C code, this probably won't be fixable. I don't know if you can force f not to be mangled by prototyping it in the C++ code as extern "C" - probably not.


All times are GMT +5.5. The time now is 01:05.