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

Discussion in 'C++' started by =?ISO-8859-1?Q?Martin_J=F8rgensen?=, Oct 28, 2006.

  1. 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

    --
    ---------------------------------------------------------------------------
    Home of Martin Jørgensen - http://www.martinjoergensen.dk
     
    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, Oct 28, 2006
    #1
    1. Advertising

  2. "Martin Jørgensen" <> wrote in message
    news:45435cf1$0$879$...
    : 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
    --
    http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
    Brainbench MVP for C++ <> http://www.brainbench.com
     
    Ivan Vecerina, Oct 28, 2006
    #2
    1. Advertising

  3. Ivan Vecerina wrote:
    > "Martin Jørgensen" <> wrote in message
    > news:45435cf1$0$879$...

    -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

    --
    ---------------------------------------------------------------------------
    Home of Martin Jørgensen - http://www.martinjoergensen.dk
     
    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, Oct 29, 2006
    #3
  4. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    Old Wolf Guest

    Martin Jørgensen wrote:
    > #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.
     
    Old Wolf, Oct 29, 2006
    #4
  5. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    red floyd Guest

    Old Wolf wrote:
    > Martin Jørgensen wrote:
    >> #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.
    >


    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 */
     
    red floyd, Oct 29, 2006
    #5
  6. Old Wolf wrote:
    > Martin Jørgensen wrote:
    >
    >>#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.


    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

    --
    ---------------------------------------------------------------------------
    Home of Martin Jørgensen - http://www.martinjoergensen.dk
     
    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, Oct 29, 2006
    #6
  7. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    Marcus Kwok Guest

    Ivan Vecerina <> wrote:
    > 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

    --
    Marcus Kwok
    Replace 'invalid' with 'net' to reply
     
    Marcus Kwok, Oct 30, 2006
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. flamesrock
    Replies:
    8
    Views:
    477
    Hendrik van Rooyen
    Nov 24, 2006
  2. Brian Takita
    Replies:
    2
    Views:
    135
    Brian Takita
    Jul 25, 2005
  3. http://links.i6networks.com

    Why '' Is Matched First Time, Not Second Time

    http://links.i6networks.com, Aug 21, 2004, in forum: Perl Misc
    Replies:
    10
    Views:
    163
    Sherm Pendley
    Aug 22, 2004
  4. Replies:
    7
    Views:
    274
    A. Sinan Unur
    Feb 14, 2006
  5. The Matchmaker
    Replies:
    2
    Views:
    321
    Jan Burse
    Sep 4, 2012
Loading...

Share This Page