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.
Related
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 am working on an Autools front-end for a C++ library. It looks like Libtool is adding C source files to the project and its causing a fair amount of trouble on some platforms. We think its causing unexplained crashes like Message “During startup program terminated with signal SIGKILL” from GDB.
The C source files cause trouble for several reasons. First, we only query CXXFLAGS and set AM_CXXFLAGS; and we don't do anything with CFLAGS or AM_CFLAGS. Second, C files need additional options in a C++ project, like -frtti and -fexceptions under GCC and options like -qrtti under IBM XL C/C++ compiler. Its not clear to me if libtool is adding the necessary options. Third, the C source files added by Libtool need additional Posix options on platforms that use Newlib, like Cygwin and MSYS. Our source files don't need the options.
I'd like to force Libtool to use C++ instead of C but I have not been able to locate an option or method to do so. I think the easiest path would be for Libtool to use lt-<some file>.cpp and CXXFLAGS rather than lt-<some file>.c and CFLAGS but I can't figure out how to do it.
How do we tell Libtool to use C++ and not C?
A related problem is How to disable C compiler in C++ Autotools project, but it only ask to use the C++ compiler for feature testing.
You could add the C compiler options you mention to the CFLAGS env var before compilation. Do you see any reasons why this would not work?
I am developing a project which I have to develop a compiler(actually a parser) besides the main project. I am using Qt 5.3 and Windows (But the result is almost the same on Ubuntu 14.04).
I am experienced in using flex and bison, however this time, firs I develop a Scanner and then Parser. I test the scanner carefully and made sure it is error less. but as I add the parser to the project many errors occurred.(for example undefined reference to yylex(), however I declared extern int yylex() and I cannot use library as I will mention) and after that when I eliminate the parser, some features which worked before are not working now! for example, now I cannot use #include <QDebug>!
When I use this header file, Compiler say there are many errors(77 error) in this library! I got confused, it has been two days I am working on this and there is no progress.
I used "Custom Build Steps" and I set the path to ${sourceDir}. In addition I added lex.yy.c,y.tab.c in SOURCES and y.tab.h in HEADERS in .pro file.
I learned how to use flex and bison via here for the first time. and for those errors I read the followings:
Undefined Reference to yylex()
How to Integrate Flex and Bison
and some other links...
Qt programs are in C++, not C.
If you have not-too-ancient versions of flex and bison, you will have no problem compiling their generated code using C++, but you need to tell the compiler that they are to be compiled in C++. (Using a combination of C and C++ is certainly possible but it requires some care.)
Using gcc, it should be sufficient to make sure that the names of the files generated by bison and flex have a .cc extension instead of .c, which you can do using the -o command-line option. (That's highly recommended in any case because it lets you choose more meaningful filenames then y.tab.c and lex.yy.c.) That requires some adjustments to your Makefile. (You can also use the %output "filename" directive in bison and %option outfile="filename" in flex, but you'll still need to adjust the dependencies in your Makefile.)
Another, less recommended, option is to use the -x c++ command-line option to gcc.
Without more details about the toolset you are using on Windows, it is not easy to give more advice, particularly for me (since I have 0 experience in Windows toolsets). But the key is to ensure that both files are compiled as C++.
From the fact that you are trying to #include a Qt header, it seems like compiling the scanner and parser as C programs is not practical. But if I am misunderstanding your project and neither the scanner nor the parser require C++, then you can do so; you'll need to declare extern "C" int yylex(); in the C++ translation unit which calls yylex. (Don't put this declaration in the scanner.l file; it won't work if you're compiling with C.)
C++ setup of flex/bison is tricky. Check out this example project:
https://github.com/ezaquarii/bison-flex-cpp-example
It is a complete, working C++ Flex and Bison "interpreter", encapsulated in a class. In fact I used it few times with Qt 4.8.
This question already has answers here:
How can I use C++ with Objective-C in XCode
(2 answers)
Closed 8 years ago.
I write a code in C++, and I want to use some of it's methods in my IOS application, so is it possible to (import) C++ library "t.cpp" to IOS application in XCode?
if yes what's the simple way to do it?
Yes, that will work without error, however you might want to change the Xcode C++ compiler settings (language level and runtime library), depending on the version of iOS you are using.
When it comes to actually using the C++ classes within your Objective-C code, you simply need to rename any files from .m to .mm.
A complication occurs when you want to include the C++ headers in Objective-C headers where both .m and .mm see that Objective-C header file. In this case you might find that you need to change many more files from .m to .mm in order for this to work, but there are ways around this if that becomes too onerous.
Just add the file to the project.
You need to rename a file from .m too .mm only if the translation unit contains a C++ header. Then, the module gets "infected" by C++ and needs to be compiled with the Objective-C++ compiler.
This is only required if any C++ header will be directly or indirectly included/imported from that module. There is no need to rename all files.
Additionally, if this C++ code depends on the C++ standard lib, you need also ensure, that the executable binary links against the C++ standard lib, via setting the appropriate build setting in the executable binary.
For example, in the target build settings of your app, add the following option to Other Linker Flags:
-lc++
e.g.:
OTHER_LDFLAGS = -ObjC -lc++
Caution:
If possible, don't include/import a C++ header in a public Objective-C header, since then all modules will be infected by C++ when they import this Objective-C header and become Objective-C++.
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.