Mixing C and C++ - for the first time - newbie question...

  • Thread starter =?ISO-8859-1?Q?Martin_J=F8rgensen?=
  • Start date
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

Hi,

Sorry for asking about something which I might be able to find on
google, but I've looked and looked and apparently I'm too stupid to
figure out how to solve this, because I can't isolate the error :)


I've been looking here:
http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html


----

1) In the top it says: You must use your C++ compiler when compiling
main() (e.g., for static initialization).

Question: I want my (7000 lines) C program to call a C++-function (to
learn more C++ ofcourse) and I'm using visual studio 2005. Doesn't that
mean I have to make the main.c file to a main.cpp file, in order to
satisfy 1) ???

---

2) I can actually easily call my C++-function as long as it doesn't take
any arguments (the build completes and works). But if I try to add
arguments, from C-main to C++-function, it doesn't work:



--- main.c ---

....
....
output_energy(energy_as_function_of_time, step, double_tmp1,
double_tmp2);

//output_energy(); // <<<<---- this works without arguments.
....
....

--- output_energy.h ---

#ifndef output_energy_H
#define output_energy_H

#include <iostream>

extern "C" void output_energy(double **energy_as_function_of_time,
unsigned long step, double cast_energy, double total_energy);

//void output_energy();

#endif



--- output_energy.cpp ---

#include "output_energy.h"

using namespace std;

//void output_energy() // <<<<--- this works...

void output_energy(double **energy_as_function_of_time, unsigned long
step, double cast_energy)
{
cout << "This works" << endl;
}


The above gives 102+ errors (with main.c - with main.cpp I think I only
get 68 errors):



------ Build started: Project: 2D_full_implicit, Configuration: Debug
Win32 ------
Compiling...
main.c
c:\programmer\microsoft visual studio 8\vc\include\cstdio(25) : error
C2143: syntax error : missing '{' before ':'
c:\programmer\microsoft visual studio 8\vc\include\cstdio(25) : error
C2059: syntax error : ':'
c:\programmer\microsoft visual studio 8\vc\include\cstdio(25) : error
C2143: syntax error : missing '{' before ':'
c:\programmer\microsoft visual studio 8\vc\include\cstdio(25) : error

/...... etc. ..... etc....
/...... etc. ..... etc....
/...... etc. ..... etc....
/...... etc. ..... etc....

c:\programmer\microsoft visual studio 8\vc\include\cstdlib(20) : error
C2059: syntax error : ':'
c:\programmer\microsoft visual studio 8\vc\include\cstdlib(21) : error
C2143: syntax error : missing '{' before ':'
c:\programmer\microsoft visual studio 8\vc\include\cstdlib(21) : fatal
error C1003: error count exceeds 100; stopping compilation
Build log was saved at "file://c:\Documents and
Settings\Dell\Skrivebord\bachelor2006\c_programming\2D_full_implicit\Debug\BuildLog.htm"
2D_full_implicit - 102 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


I think I need to convert main.c to main.cpp so I get static
initialization (whatever that means). Is this correct?

I think I get 68 errors with main.cpp because I use malloc() in my
C-program many places... Should I convert all those lines to "new ....
something" since I think malloc() doesn't exist in C++?



Best regards
Martin Jørgensen
 
I

Ivan Vecerina

: 1) In the top it says: You must use your C++ compiler when compiling
: main() (e.g., for static initialization).
:
: Question: I want my (7000 lines) C program to call a C++-function (to
: learn more C++ ofcourse) and I'm using visual studio 2005. Doesn't
that
: mean I have to make the main.c file to a main.cpp file, in order to
: satisfy 1) ???
Yes.

: 2) I can actually easily call my C++-function as long as it doesn't
take
: any arguments (the build completes and works). But if I try to add
: arguments, from C-main to C++-function, it doesn't work:
....
: --- output_energy.h ---
:
: #ifndef output_energy_H
: #define output_energy_H
:
: #include <iostream>
:
: extern "C" void output_energy(double **energy_as_function_of_time,
: unsigned long step, double cast_energy, double total_energy);

This seems ok, although I find it easier to enclose all declarations in
the header within a single:
#ifdef __cplusplus
extern "C" {
#endif

// ... all decls ...

#ifdef __cplusplus
}
#endif


: --- output_energy.cpp ---
:
: #include "output_energy.h"
:
: using namespace std;
:
: //void output_energy() // <<<<--- this works...
:
: void output_energy(double **energy_as_function_of_time, unsigned long
: step, double cast_energy)
: {
: cout << "This works" << endl;
: }

I think that the problem is that extern "C" needs to be
specified for the implementation of the functions as well.


: I think I need to convert main.c to main.cpp so I get static
: initialization (whatever that means). Is this correct?
Yes, but this would not be causing the link errors you see.

: I think I get 68 errors with main.cpp because I use malloc() in my
: C-program many places... Should I convert all those lines to "new ....
: something" since I think malloc() doesn't exist in C++?

You could easily rename your current main() to cmain(),
and call that function from a C++ main() function.

This said: malloc() does exist in C++.
The problem you see is probably caused by the fact that,
in C++, there is no implicit conversion from void* to
pointers to another type.
As a result, you need to convert:
double* p = malloc( 16*sizeof(double) ); // ok in C only
into:
double* p = (double*)malloc( 16*sizeof(double) ); // ok C & C++

It typically doesn't take much more than this to get all source
files of a C program to compile with a C++ compiler.
This might the the easiest way for you to start using C++
(rather than use extern "C" and mixed compilation).

The real challenge is to learn to replace C techniques


hth -Ivan
 
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

Ivan said:
-snip-

: I think I need to convert main.c to main.cpp so I get static
: initialization (whatever that means). Is this correct?
Yes, but this would not be causing the link errors you see.

: I think I get 68 errors with main.cpp because I use malloc() in my
: C-program many places... Should I convert all those lines to "new ....
: something" since I think malloc() doesn't exist in C++?

You could easily rename your current main() to cmain(),
and call that function from a C++ main() function.

I read your reply many hours ago, but have spent much time trying to
figure out how to make it work.... And *NOW* my program works :)

I'm really happy I did this.... I couldn't make it work, using a cmain()
function.... Perhaps if I try it again next time, it'll work.

But it's also a bit "ugly" I think but on the other hand you're right, I
think. Then I probably don't need to cast those malloc return types
explicity.
This said: malloc() does exist in C++.
The problem you see is probably caused by the fact that,
in C++, there is no implicit conversion from void* to
pointers to another type.

Exactly... That was (most of) my problem... I had to go through 68
malloc calls... The other thing was that it wouldn't work if I used
#ifdef __cplusplus on a C++ header... And on system headers... Damn...

Also confusing was that I had a library in C which I didn't had the
source code for. I've had the compiler setting on C++ for a files set a
long time but finally I figured it out and now it's on "default" so
it'll determine if it'll run a C compiler or C++, based on the file
extension, I think... So now it doesn't complain about my external library.

I'm really happy now. This is my first time mixing/linking 2 different
programming languages. Those guys that made something like that possible
must be clever :)
As a result, you need to convert:
double* p = malloc( 16*sizeof(double) ); // ok in C only
into:
double* p = (double*)malloc( 16*sizeof(double) ); // ok C & C++

Thanks so much for that :)
It typically doesn't take much more than this to get all source
files of a C program to compile with a C++ compiler.

Yes, if you know how to use this #ifdef __cplusplus properly and insert
it correctly at exactly the right location for all header files (I have
8-10 others) :)
This might the the easiest way for you to start using C++
(rather than use extern "C" and mixed compilation).

The real challenge is to learn to replace C techniques

Yep, but now I can practice... So I'm really glad... And hopefully learn
more C++...


Best regards
Martin Jørgensen
 
O

Old Wolf

Martin said:
#ifndef output_energy_H
#define output_energy_H

#include <iostream>

extern "C" void output_energy(double **energy_as_function_of_time,
unsigned long step, double cast_energy, double total_energy);

#endif

The above gives 102+ errors (with main.c - with main.cpp I think I only
get 68 errors):

"#include <iostream>" and "extern "C"" are C++-isms. You cannot
include those in a C header file. Take them out.

If you want to include a C header from C++ code, write:
extern "C" {
#include "header.h"
}

Also, ignore the ridiculous advice you got to try and compile C
code with a C++ compiler. You wouldn't compile Java code with
a C compiler either, would you? Compile C files as C and C++
file as C++. They are different languages and there is
absolutely no need to pull this stunt.
 
R

red floyd

Old said:
"#include <iostream>" and "extern "C"" are C++-isms. You cannot
include those in a C header file. Take them out.

If you want to include a C header from C++ code, write:
extern "C" {
#include "header.h"
}

Also, ignore the ridiculous advice you got to try and compile C
code with a C++ compiler. You wouldn't compile Java code with
a C compiler either, would you? Compile C files as C and C++
file as C++. They are different languages and there is
absolutely no need to pull this stunt.

Better would be:

#ifndef output_energy_H
#define output_energy_H

#ifdef __cplusplus
extern "C" {
#endif

// C compatible declarations

#ifdef __cplusplus
}
#endif

#endif /* output_energy_H */
 
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

Old said:
"#include <iostream>" and "extern "C"" are C++-isms. You cannot
include those in a C header file. Take them out.

I think that was a mistake I previously did... Because output_energy()
is a C++ function... So it means it doesn't compile with a C compiler
anyway.

Therefore I don't need the extern "C"... Isn't that right?
If you want to include a C header from C++ code, write:
extern "C" {
#include "header.h"
}

Also, ignore the ridiculous advice you got to try and compile C
code with a C++ compiler. You wouldn't compile Java code with
a C compiler either, would you? Compile C files as C and C++
file as C++. They are different languages and there is
absolutely no need to pull this stunt.

Ok... My only problem left is to make it work on linux (can't figure out
how to make the makefile work)... But I think I got a little help in
gnu.g++.help for this issue... :)


Best regards
Martin Jørgensen
 
M

Marcus Kwok

Ivan Vecerina said:
This said: malloc() does exist in C++.
The problem you see is probably caused by the fact that,
in C++, there is no implicit conversion from void* to
pointers to another type.
As a result, you need to convert:
double* p = malloc( 16*sizeof(double) ); // ok in C only
into:
double* p = (double*)malloc( 16*sizeof(double) ); // ok C & C++

Casting the result of malloc is necessary in C++ (as you said), but it
is actually discouraged in C:

http://www.c-faq.com/malloc/mallocnocast.html
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top