When compiling a c file that uses old style function definition like
int foo(a)
int a;
{
...
}
g++ will give and error: ‘a’ was not declared in this scope.
gcc can parse this.
Is there a way to let g++ recognize this?
This comes up as an issue to me because I'm compiling a mix of c and c++ files.
A related question is what's the standard practice
of building this type of mixed source? Running g++ on all files or only the cc files? The former is convenient but keeps getting me some trouble because of the inconsistencies between c and c++ specification(for example, char[4]="four";)
Is there a way to let g++ recognize this?
This syntax is not supported in C++.
Running g++ on all files or only the cc files?
See e.g. Compiling C++ programs from the GCC docs:
C++ source files conventionally use one of the suffixes .C', .cc, .cpp, .CPP, .c++, .cp, or .cxx; C++ header files often use .hh, .hpp, .H, or (for shared template code) .tcc; and preprocessed C++ files use the suffix .ii. GCC recognizes files with these names and compiles them as C++ programs even if you call the compiler the same way as for compiling C programs (usually with the name gcc).
However, the use of gcc does not add the C++ library. g++ is a program that calls GCC and treats .c, .h and .i files as C++ source files instead of C source files unless -x is used, and automatically specifies linking against the C++ library. This program is also useful when precompiling a C header file with a .h extension for use in C++ compilations.
So two possibilities:
Run gcc on C files, and g++ on C++ files.
Run gcc on all files.
In both cases you will need to link with g++ (or gcc -lstdc++).
Oli is correct: C++ doesn't support old-style function definitions.
Compile C with a C compiler (such as gcc).
Compile C++ with a C++ compiler (such as g++).
They're two different (though closely related) languages. You can use C++'s extern "C" feature to invoke C code from C++ and vice versa; see section 32 of the C++ FAQ Lite for more information.
If you are going to compile both C and C++, you are better off compiling always with gcc (it will choose the language based on the file extension) than g++ (will always compile as C++). You will need to change your linker options to include C++ standard library (and -lm if you use it) as those are automatically added by g++ but not gcc.
Alternatively, a better option is to call the g++ for C++ and gcc for C files. That should not be too hard to manage by configuring the build system.
Related
I have a .so library where all code was written in plain ANSI C, so compiling it is straightforward. Now, I need to add C++ code in it. What would be the compilation process now?
Do I have to compile C++ files with g++ and the rest with gcc, but what about linking into .so file, do I do this with g++?
Thanks!
Yes,
Compile .c with gcc
Compile .cpp with g++
Link with g++
Note:
If a C++ function needs to be invokable from C code, wrap it in extern "C" { ... }.
I have ported a project to an arm cortex M7 chip, and am mucking around with makefiles for the first time, im using the gnu-gcc compiler collection.
Is it advisable to compile "c" code with the gcc driver and, compile the "c++" (app) code with the g++ driver, and then link. The c code is all low level (header files)register access addresses etc and contains no functions (yet) or attached source files.
Or can i compile all with the g++ compiler if the header files can be modified to compile with g++ if needed.
I have it set so gcc is compiling the c files, and g++ is compiling c++ and linking.
The only differences between gcc and g++ are that:
when the driver is used to invoke the linker, g++ causes libstdc++ to be linked as part of "stdlibs", while gcc will link only libc.
g++ will compile .c, .h and .i files as C++ unless the -x option is specified.
Both drivers will compile C or C++ depending on either the filename extension, or command-line switches. If you invoke the compiler-driver for compilation only and invoke the linker (ld) directly, using gcc or g++ -x, it makes no difference which you use.
Equally, if you invoke the gcc driver for C++ code and explicitly link stdlibc++ it also makes no difference - so long as your crt0.o is not C-only - a C++ runtime start-up must invoke global static constructors before main()) - this is likely to already be the case.
The definitive word from the documentation:
3.3 Compiling C++ Programs
C++ source files conventionally use one of the suffixes ‘.C’, ‘.cc’, ‘.cpp’, ‘.CPP’, ‘.c++’, ‘.cp’, or ‘.cxx’;
C++ header files often use ‘.hh’, ‘.hpp’, ‘.H’, or (for shared
template code) ‘.tcc’; and preprocessed C++ files use the suffix
‘.ii’. GCC recognizes files with these names and compiles them as C++
programs even if you call the compiler the same way as for compiling C
programs (usually with the name gcc).
However, the use of gcc does not add the C++ library. g++ is a program
that calls GCC and automatically specifies linking against the C++
library. It treats ‘.c’, ‘.h’ and ‘.i’ files as C++ source files
instead of C source files unless -x is used. This program is also
useful when precompiling a C header file with a ‘.h’ extension for use
in C++ compilations. On many systems, g++ is also installed with the
name c++.
When you compile C++ programs, you may specify many of the same
command-line options that you use for compiling programs in any
language; or command-line options meaningful for C and related
languages; or options that are meaningful only for C++ programs. See
Options Controlling C Dialect, for explanations of options for
languages related to C. See Options Controlling C++ Dialect, for
explanations of options that are meaningful only for C++ programs.
If you want to use just one, I suggest you use gcc and separately invoke the linker or explicitly link -libstdc++. That way the compilation mode will be dependent on the filename extension. Using g++ -x to compile C code is just going to cause confusion.
I read somewhere that c++ object files must be linked only through g++ not gcc. Is it true? if yes, then how to link object files belong to c, c++ and asm?
If you use g++ to link, then it will automatically link with the C++ runtime library. If you link with gcc you have to link with the runtime manually.
That's the only difference.
The gcc and g++ programs are only special front-end wrapper programs, that invoke the correct preprocessor, compiler, assembler and linker for the files provided.
Yes, you have to use G++ to link C++ due to name mangling.
See the topic here https://en.wikipedia.org/wiki/Name_mangling
C++ names are C-abi compatible, you can link C++ object files to C code.
I have confused about the different between embedding Clips into C and C++.
I have succeed to embed Clips into C Program obeying the steps on the Advanced Programming Guide (Chapter 4.17)
Now, I want to embed Clips into a C++ Program, and I have some question.
.c.o :
gcc -c -Wall -Wundef -Wpointer-arith -Wshadow -Wcast-qual \
-Wcast-align -Winline -Wmissing-declarations -Wredundant-decls \
-Wmissing-prototypes -Wnested-externs \
-Wstrict-prototypes -Waggregate-return -Wno-implicit $<
clips : $(OBJS)
gcc -o clips $(OBJS) -lm -ltermcap
OBJS represents the .o files.
When I embed Clips into C program, I use makefile download from the github(shown as above). It uses "gcc" wonder if I should change the "gcc" into "g++" and do some other change.
the source file is .c file and .h file , should I change them into .cpp file and .hpp file?
there also clipsmm on the sourceforge described as A C++ CLIPS Interface, I download and read it's doc, I don't quite understand it. Does it just provide some .hpp file or a totally new clips?
I have use the C functions offered in the Advanced Programming Guide, I don't know if I can use these function when embedding Clips into C++?
Some stupid questions
Thank you for any answer or idea.
Remember that C++ is for the most part backwards compatible with C.
If the clips headers contain extern "C" for their function prototypes in C++, you can use it just the same as for C. Just include the header files, and link with the library/object files generated from the C source files.
Section 1.2 in the Advanced Programming Guide has some notes on C++ compatibility:
1.2 C++ COMPATIBILITY
The CLIPS source code can now be compiled using either an ANSI C or
C++ compiler. Minimally, non-ANSI C compilers must support full ANSI
style function prototypes and the void data type in order to compile
CLIPS. If you want to make CLIPS API calls from a C++ program, it is
usually easier to do the integration by compiling the CLIPS source
files as C++ files. This removes the need to make an extern "C"
declaration in your C++ program for the CLIPS APIs. Some programming
environments allow you to specify the whether a file should be
compiled as C or C++ code based on the file extension. Other
environments allow you to explicitly specify which compiler to use
regardless of the extension (e.g. in gcc the option “-x c++” will
compile .c files as C++ files). In some environments, the same
compiler is used to compile both C and C++ programs and the compiler
uses the file extension to determine whether the file should be
compiled as a C or C++ program. In this situation, changing the .c
extension of the CLIPS source files to .cpp usually allows the source
to be compiled as a C++ program.
Rather than changing the file extensions, I'd suggest using the "-x c++" option with gcc for the .c files in your makefile. You can use g++ with your c++ source files. When you compile the source files in this manner, you can invoke the functions documented in the APG from your C or C++ code directly without the need for wrapping the function prototypes with extern "C".
I haven't used clipsmm, but it appears to be a set of C++ wrapper classes for the core CLIPS source code.
I have a file named main.cpp which includes iostream.
I compiled main.cpp and it worked without errors, so my question is: I compiled main.cpp and I did not link iostream with main.cpp, so how could this be possible? Or did the compiler linked the iostream automatically?
The functions in iostream are part of the C++ standard library, which you usually don't need to link explicitly.
If you use a compiler that's not strictly a C++ compiler, you sometimes need to add something like -lstdc++ (at least, I do if I use gcc rather than g++).
The iostream library is part of the “compiler”, in the
largest sense of the word, and if you invoke the linker through the C++
compiler driver, (g++, cl, etc.), it will be automatically included;
IDE's also generally arrange for it to be automatically included. If
you invoke the linker directly (ld, link, etc.), then you'll
generally have to specify it explicitly. The same thing is true if the
compiler driver doesn't understand C++ (the case of gcc).