How to exclude certain #include directives from C++ stream? - c++

I have this C++ file (let's call it main.cpp):
#include <string>
#include "main.y.c"
void f(const std::string& s) {
yy_switch_to_buffer(yy_scan_string(s.c_str()));
yyparse();
}
The file depends on main.y.c, which has to be generated beforehand by means of bison util. In other words, I can't compile main.c file if I forget to run bison main.y before it. And it's perfectly OK, this is how I want it. Now I'm trying to build .d file from Makefile, using this command:
$ c++ -MM main.c > main.d
main.cpp:2:10: error: main.y.c: No such file or directory
I fail here, since main.y.c is not ready yet. I think that I should somehow quote my #include directive in the main.c file to make it invisible for c++ -MM process.

This sounds like a job for a makefile. You can set the dependencies such that main.c depends on main.y.c, and main.y.c has a rule to build it from the bison code.

You can indicate in your makefile that main.c depends on main.y.c so that it'll run the bison process before it tries to compile main.c.
As an alternative (which I think is probably not what you want to do) is that you can have your makefile pass a macro to the compiler to indicate whether or not main.y.c exists and use an #if directive to include (or not) main.y.c.
#if EXISTS_MAIN_Y_C
#include "main.y.c"
#endif

Related

linker input file unused because linking not done, I can't get .o

I have a template class of a binary tree, tree.tpp and tree.h. I have done a test with the class but I can't compile it
#include <cstdlib>
#include <iostream>
#include "arbolbinario.h"
using namespace std;
int main(int argc, char** argv) {
ArbolBinario<int> pila(45);
return 0;
}
And I'm having the following error when I do: g++ -c -o ./tree.o ./tree.tpp -I ./tree.h
g++: warning: ./tree.tpp: linker input file unused because linking not done
(I'm working with netbeans)
.tpp is not one of the file endings recognized by g++, see its documentation.
Therefore g++ assumes that you want the file to be passed to the linker directly. But since you used the -c flag, which indicates that you want g++ to only compile, but not invoke the linker, you get that error message.
The solution is to tell g++ what kind of file it is that you are passing it explicitly:
g++ -c -o ./tree.o -x c++ ./tree.tpp -I ./tree.h
or, better, rename your C++ source file use one of the common file endings for C++ source files, e.g. .cpp, .cc, .cxx, etc. That would result in less trouble with build tools and less confusion for others looking at your project.
As noted in the question comments -I ./tree.h also is clearly wrong, but not the cause of this particular error (and probably it just doesn't belong there at all).
However:
If your .tpp contains the implementation of methods of a class template, then you should not rename it (.tpp is appropriate in that case), but you also should not compile it as translation unit at all. That means it should not appear in any g++ command.
.tpp files implementing a template classes methods need to be included in the .h file with the class template definition, instead. Otherwise you will get linker errors later when you try to link your files, see Why can templates only be implemented in the header file?.
The -c flag tells GCC to only compile the input source files, not to do any linking.
If you want the compiler to link the object files into an executable binary, you need to remove the -c flag.

Including an external header file in Flex

I am writing a program using flex that takes input from a text file and splits them into some tokens like identifier, keywords, operators etc. My file name is test.l. I have made another hash table program which includes a file named SymbolTable.h . Is there any way to include this header file in my test.l file so that I can make some operations (for example: inserting the identifiers into the hash table)while reading the input? I have already tried to include it but when I try to compile using gcc lex.yy.c -lfl , it generates an error message saying:
"fatal error: SymbolTable.h: No such file or directory."
Please help me on how to include the header file or in any other way I can do the desired operation I stated above.
It seems your issue is not with flex, but with how the C language handles the different syntax. This is explained in this question: What is the difference between #include <filename> and #include "filename"?.
You probably have:
#include <SymbolTable.h>
when you should have
#include "SymbolTable.h"
As you did not show the actual code you used it was hard to properly answer.
For simple application you can use a little template of bison/yacc project of mine.
gram.y
%{
#include <stdio.h>
#include <stdlib.h>
%}
// tokens here
%%
// rules here
%%
int main() {
return yyparse();
}
scan.l:
%{
#include <stdio.h>
//include a YACC grammar header
//#include "gram.h"
%}
%%
. /*LEX RULES*/;
%%
// C code
int yywrap() {
return 1;
}
Makefile:
all: gram
gram: gram.c gram.h scan.c
gcc gram.c scan.c -lfl -ly -o gram
gram.c: gram.y
yacc -d gram.y -o gram.c
scan.c: scan.l
flex -o scan.c scan.l
scan: scan.c
gcc scan.c -lfl -o scan
Scanner uses the header file generated from bison in this example. But surely you can include in the same place some other header file.
To compile your lexer just type make scan or just make to compile lexer and grammar at the same time.
Have a good luck in your lexer journey!
Your include statement worked just fine. The compiler couldn't find your file because it is not in the include search path. Try adding -I. when invoking gcc. Like : gcc -I.

Confusion between including header files and source files in main program

I have heard that we should write the declarations in a header file and the definition in a source file, with both the source and the header having the same name. And then just include the header in the source.
Here is an example myFile.h:
void printer (void);
Here is the implementation of printer in myFile.cpp:
#include "myFile.h"
#include <iostream>
using namespace std;
void printer ()
{
cout<< "I am a printer";
}
Here is my main.cpp:
#include "myFile.h"
int main ()
{
printer();
return 0;
}
Now when I run the program, I get the expected error: undefined reference to printer. But when I see code on github or other projects I see that usually they have included the header file and not the source file. I also tried using the header guards ifndef but still the same error came.
The main program is successfully compiled if:
If i include myFIle.cpp in myFile.h
If i include just myFile.cpp in main
What I the general practice while doing the same?
You should include your myFile.cpp in the linking process:
g++ myFile.cpp main.cpp
The error message undefined reference to printer is actual a linker error, not a compiler error.
Explanation
If you use only g++ main.cpp compiler won't create code from myFile.cpp. He knows that there should be a function with the signature void printer(void), but he doesn't now yet where this function is. He completely ignores this fact, since you can provide pre-compiled object files ("myFile.o") and link those later:
g++ myFile.cpp -c # compile myFile.cpp
g++ main.cpp -c # compile myFile.cpp
g++ myFile.o main.o # link both files together.
-c will tell g++ only to compile the files, but not link them together to an executable. This is done by a linker (g++ will probably call ld in your configuration). The linker will create an executable which contains all needed libraries like libc++ and actual code.
IDE remarks
If you use an IDE make sure that all needed files are included in the project. This includes all header and source files and linkage options for additional libraries.
When yourself define a header file and want to include it, you should enclose it "", such as :
#include "myFile.h"
#include "myFile.h" // would be better.
It seems you forgot the " surrounding the include.
You should use
#include "myFile.h"
or
#include <myFile.h>
the later is rather for system libraries. Both forms differ in the way the search the file.
You find more details on
http://msdn.microsoft.com/en-us/library/36k2cdd4%28v=vs.71%29.aspx

Cannot include standard C++ libraries with MinGW

I have a Qt C++ application that compiles fine with the MSVC compiler. Now I'm trying to compile the same application with MinGW so that I can eventually port it to Mac OSX. However, when doing so I'm getting an error on all the standard includes:
#include <algorithm>
#include <ctime>
#include <map>
#include <sstream>
#include <vector>
And the compiler outputs:
..\trunk\stable.h:29:21: error: algorithm: No such file or directory
..\trunk\stable.h:30:17: error: ctime: No such file or directory
..\trunk\stable.h:31:15: error: map: No such file or directory
..\trunk\stable.h:32:19: error: sstream: No such file or directory
..\trunk\stable.h:33:18: error: vector: No such file or directory
I really don't understand what could be causing this issue. Any suggestion?
This is one of the more common errors you will see if your source is C++ but is being compiled as C.
This in turn can happen if the source uses .C (note capital C) extension for C++ files. If the source is used in a case-insensitive file system (like all of the windows ones generally) then make probably won't be able to properly tell whether to compile them as C or C++.
By default, make (including the mingw version) will compile C++ source from extensions .C, .cc and .cpp. (This page has the details).
You have 3 options:
rename your sources to one of the above extensions. generally .cc and .cpp are the easiest to work with.
if ALL of the sources in the makefile, you can go CC=mingw32-g++ mingw32-make -f Makefile.Debug
you can add this to the makefile or one of the included files:
%.o: %.c++
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $# $<
but this will only work if the makefile(s) haven't changed the rules for compilation.

Compilation failing - no #include - boost

I'm trying to compile a third-party library, but g++ is complaining about the following line:
typedef boost::shared_ptr<MessageConsumer> MessageConsumerPtr;
The strange thing is, there is no #include directive in the file - and it is clearly supposed to be this way; there are about 60 files with the same (or very similar) issues. Clearly if there was an #include directive referencing the relevant boost header this would compile cleanly.
My question is: how can I get g++ to somehow automagically find the relevant symbol (in all instances of this issue, it is a namespace that can't be found - usually std:: or boost::) by either automatically processing the relevant header (or some other mechanism).
Thanks.
Edit
My current g++ call looks like:
g++ -fPIC -O3 -DUSING_PCH -D_REENTRANT -I/usr/include/boost -I./ -c MessageInterpreter.cpp -o MessageInterpreter.o
You can use the -include command line option:
g++ -include boost/shared_ptr.hpp ...
From the man page:
-include file
Process file as if "#include "file"" appeared as the first line of
the primary source file. However, the first directory searched for
file is the preprocessor's working directory instead of the
directory containing the main source file. If not found there, it
is searched for in the remainder of the "#include "..."" search
chain as normal.
Create your own wrapper .h file that includes the boost .h and then the broken .h .
Or (very fragile) ensure that you precede every use of the broken .h with boost .h .
Perhaps the third-party library is designed in such a way that you should always include a certain "main" header file in order to get the dependencies right.
Otherwise, you can add #include <boost/shared_ptr.hpp> before including the third-party header file that is giving the error message.