Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When mixing C and C++ code, does main() need to be in the C++ part?

Tags:

c++

c

gcc

linker

clang

I have a C program that I need to interface with a C++ library (ROS). Normally, it's not too difficult to interface C code with C++ code with a wrapper using extern "C" and using the C++ compiler to link, but I've never had to do it where main was in the C portion.

The C++ FAQ indicates that this is a bad thing:

Here are some high points (though some compiler-vendors might not require all these; check with your compiler-vendor’s documentation):

  • You must use your C++ compiler when compiling main() (e.g., for static initialization)

But I see another source saying it should be okay these days:

At one time, most C++ compilers required that function main be compiled by the C++ compiler. That requirement is not common today, ...

Why would it matter whether main is in the C portion or the C++ portion? How much trouble would I be in if I try to link code where it's in the C portion using common linkers today (mainly GCC's and Clang's)?

like image 519
Dominick Pastore Avatar asked Feb 14 '21 03:02

Dominick Pastore


People also ask

Is it OK to mix C and C++?

If the C++ compiler provides its own versions of the C headers, the versions of those headers used by the C compiler must be compatible. Oracle Developer Studio C and C++ compilers use compatible headers, and use the same C runtime library. They are fully compatible.

How do I combine C and C++ codes?

You will need to wrap the C header file inclusion with the extern "C" { } as shown above. Then, you can just try to compile it (only the source file containing the main function) in a C++ compiler, and the rest of the C code with the C compiler, and then link the whole thing together.

Can you use C libraries in C++?

Yes - C++ can use C libraries.

Do you need extern C?

You need to use extern "C" in C++ when declaring a function that was implemented/compiled in C. The use of extern "C" tells the compiler/linker to use the C naming and calling conventions, instead of the C++ name mangling and C++ calling conventions that would be used otherwise.

Can you mix C and C++ in the same program?

Mixing C and C++ Code in the Same Program The C++ language provides mechanisms for mixing code that is compiled by compatible C and C++ compilers in the same program. You can experience varying degrees of success as you port such code to different platforms and compilers.

What are the downsides of mixing C and C++?

The down-side is that you’ll need to update your C-style code in certain ways, basically because the C++ compiler is more careful/picky than your C compiler. The point is that the effort required to clean up your C-style code may be less than the effort required to mix C and C++, and as a bonus you get cleaned up C-style code.

What does main () return in C and C++?

What does main () return in C and C++? According to coding standards, a good return program must exit the main function with 0. Although we are using void main () in C, In which we have not suppose to write any kind of return statement but that doesn’t mean that C code doesn’t require 0 as exit code.

Should I switch from C to C++?

When transitioning from C to C++, you are not likely to refresh your entire code base. Instead, you will need to maintain a mix of C and C++ code, hopefully getting the two sets of code to work together. One common situation is that you have a C++ library with C-style interfaces.


1 Answers

One easy way to work around this is to rename your C main() and call it from a new C++ main()

As in:

// in ypur current C main module

int my_c_main(int argc, char* argv[]) /* renamed, was main() */
{
   /* ... */
]

// in a c++ module...

int main(int argc, char* argv[])
{
    extern "C" int my_c_main(int argc, char* argv[]);

    // if your c main() requires environment variables passed in envp,
    // You can allocate space for strings and an array here and pass
    // the environment variables you'll need, as the third parameter
    // to my_c_main(), or pass environ, if your system has
    // it defined in unistd.h

    return my_c_main(argc, argv);
}
like image 99
Michaël Roy Avatar answered Sep 24 '22 03:09

Michaël Roy