These warnings indicate that the compiler doesn't know what kinds of functions sqrt and printf are, so it assumes that they return an int, which is usually a poor assumption. To clue the compiler in as to their types, we need to specify the proper prototypes. This is easily done by including the header files where these functions are prototyped:cfile.c(3) : warning C4013: 'sqrt' undefined; assuming extern returning int cfile.c(5) : warning C4013: 'printf' undefined; assuming extern returning int
This suppresses the warnings about the functions being unknown. However, we are now getting another warning:#include <math.h> #include <stdio.h>
This is because the sqrt function returns a double, yet we are assigning it to an int. To suppress this warning, we need to cast the return value to an intCFile.c(8) : warning C4244: 'initializing' : conversion from 'double ' to 'int ', possible loss of data
Now the file will compile without warnings or errors.int i = (int)sqrt(25);
Or, if you would rather use the "c" versions of the header files (without the extension), you can do this:#include <math.h> #include <stdio.h> int i = static_cast<int>(sqrt(25));
The C++ code now compiles without warnings or errors.#include <cmath> #include <cstdio>
Wrapping C header files in C++
So we are almost there. To get the output from the C++ code, we need to call the C++ function from the C code by adding a call to it in main:In C: i = 5, d = 5
void main(void)
{
int i = (int) sqrt(25);
double d = sqrt(25);
printf("In C: i = %i, d = %g\n", i, d);
cpp_stuff();
}
This code generates a warning during the compile and an error during the link.
The reason the compiler generates a warning is because it doesn't know what cpp_stuff is. (The same problem we had with sqrt and printf). So, we need to prototype it in our C file. (We don't have a header file that we can include.) The linker error is because the C++ compiler mangled the function name into a non-C compatible function name.CFile.c(9) : warning C4013: 'cpp_stuff' undefined; assuming extern returning int Linking... CFile.obj : error LNK2001: unresolved external symbol _cpp_stuff Debug/CandCPP.exe : fatal error LNK1120: 1 unresolved externals Error executing link.exe.
To fix the compiler warning, we prototype the function before main:
To fix the linker error, we need to tell the C++ compiler to disable name mangling during the compile by using the extern keyword:void cpp_stuff(void);
extern "C" void cpp_stuff(void)
{
...
}
This fixes all of the problems we encountered when we attempted mix C and C++ code in the same project. The
entire project will compile and link without warnings or errors. The output from the program looks like:
In C: i = 5, d = 5 In CPP: i = 5, d = 5
The complete code for both files:
CFile.c:
#include <math.h> // for sqrt()
#include <stdio.h> // for printf()
void cpp_stuff(void);
void main(void)
{
int i = (int) sqrt(25);
double d = sqrt(25);
printf("In C: i = %i, d = %g\n", i, d);
cpp_stuff();
}
CPPFile.cpp:
#include <math.h> // for sqrt()
#include <stdio.h> // for printf()
// use extern "C" so the C file can link to this
extern "C" void cpp_stuff(void)
{
int i = (int)sqrt(25);
double d = sqrt(25);
printf("In CPP: i = %i, d = %g\n", i, d);
}