bison/yacc using defines in %union - makefile

I have TOKEN_LEN defined in a header file stuff.h. I'd like to use it in the %union section:
%union {
int ival;
char sval[TOKEN_LEN];
}
However, including it in the %{ ... %} section just copies that block verbatim, bison will error out because TOKEN_LEN is not defined.
I can use flex -DTOKEN_LEN=100 ... in the makefile but that means TOKEN_LEN is defined in two places. Yes, in flex as opposed to bison!
I tried defining it solely in the makefile like this:
DEFS=TOKEN_LEN=100
Then using:
flex -D${DEFS} ...
bison -D${DEFS} ...
gcc -D${DEFS} ...
But make doesn't like this for this reason:
<command line>:1: error: %define variable 'TOKEN_LEN' is not used
Makefile:4: recipe for target 'stuff' failed
make: *** [stuff] Error 1
Is there a solution to this? The preference would be to have TOKEN_LEN defined only in stuff.h.

The best way to do this with bison is to use the bison-specific %code directive:
%code requires {
#include "stuff.h"
}
in the top of your bison file. This will put this include in the bison generated file(s) before the definition of YYSTYPE (the %union)
Doing this with generic yacc is harder -- you can use the %{..%} directive for the yacc parser itself, but you also need to ensure you put #include "stuff.h" before #include "y.tab.h" in every file that has the latter include.

Related

gcc not respecting my include directory order

I'm attempting to build some code using a temporary version of an include file in my local ../include/records directory. The orignal lives in /home/apps/include/records. I have my gcc command set to search ../include before /home/apps/include, but it's still picking up the original module from /home/apps/include and reporting errors. If I rename the original in /home/apps/include, then gcc picks up my local edited copy and it compiles clean. So, what's up with the include order...? This 'local include first' logic has always worked for me in the past, but this may be the first time I've used it since migrating from AIX to Linux.
Is there something beyond the order of the -I command-line options that could be overriding the requested include order?
The source module include statment is:
#include "records/novarec.h"
and the gcc command line looks like this:
$make
gcc -DLINUX64 -c -g -I. -I../include -I/home/apps/include -I/home/apps/include/em -I/home/apps/include/odbc -Wno-implicit-function-declaration -Wno-implicit-int -Wno-format-security -Wno-format-truncation -Wno-discarded-qualifiers novaget.c
The compiler complains about an undefined value that's in my local copy of novarec.h, but not in the production /home/apps/include/records/novarec.h:
novaget.c: In function ‘calcComscoreDemoV1’:
novaget.c:2651:15: error: ‘CSCD_W21_49’ undeclared (first use in this function); did you mean ‘CSCD_W25_49’?
fval = *(dm+CSCD_W21_49);
^~~~~~~~~~~
It seems like the answer is this:
My module called in 2 include files. The first one also includes the second one - and the first one lives in /home/apps/include. That seems to make gcc search there for the second include file - even though /home/apps/include is not the first include directory in my path.
When I reverse the 2 include statements in my .c file, the correct path is followed for novarec.h. i.e. when I code:
#include "spottvdemos.h" (this modules has a #include "records/novarec.h")
#include "records/novarec.h"
novarec.h gets picked up from /home/apps/include, but when I code:
#include "records/novarec.h"
#include "spottvdemos.h"
novarec gets picked up from ../include, which is what I wanted.

gfortran does not process #define in include [duplicate]

I would like to understand how the preprocessor inlines includes into the code in Fortran. With C, it's pretty simple:
Test.c:
#include <stdio.h>
int main(void) {
return 0;
}
Then I compile using:
gcc -E test.c
Then it displays the content generated by the C preprocessor, as expected.
Now assume I have this Fortran code:
Test.f:
program test
include "mpif.h"
call mpi_init
call mpi_finalize
end
Then I run:
gfortran -E -cpp test.f // For some reason I need -cpp when using -E in Fortran
But I won't have the expected result, which is the generated include embedded into the code.
Instead, I have this:
# 1 "test.f"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.f"
program test
include 'mpif.h'
call mpi_init
call mpi_finalize
end
What am I doing wrong here?
Fortran has its own include directive which must not be confused with the preprocessor directive #include. As far as I understand it, the included code is not embedded into the master file, but the compiler instead continues to compile from the include file, and returns to the master file at the end of that file. From here:
The INCLUDE statement directs the compiler to stop reading statements
from the current file and read statements in an included file or text
module.
Also, included files are not preprocessed further, while #included ones are.
Note, that there is also a naming convention that enables the preprocessor only on files with capital suffixes *.F and *.F90. If you want to preprocess *.f or *.f90 files, you need to specify that in a compile option, e.g. -cpp for gfortran, and -fpp for ifort.

No compile error without multiple inclusion guard

Not including the #ifndef guard to prevent multiple header file inclusions, does not throw compile error. Why is that?
// main.c
#include <stdio.h>
#include "declare.h"
#include "declare.h" //Shouldn't I get compiler error here
int main(){
printf("Hello World\n");
}
// declare.h
#define a 1 //just this define in declare.h file
Command used to compile: gcc main.c -std=c89
Including a header multiple times is not an error, either with or without guards.
Guards prevent you from redefining objects and functions, when you do so.
But you haven't done that. You've just redefined a macro with the same value it had before. Which is fine.
You can test this by just compiling the following file:
#define a 1
#define a 1
It's fine.
[C89: 6.8.3]: [..] An identifier currently defined as a macro without use of lparen (an object-like macro) may be redefined by another #define preprocessing directive provided that the second definition is an object-like macro definition and the two replacement lists are identical. [..]
Start putting more complex stuff in that header and you'll see a problem.

conditional compliation based on variable into makefile

Inside my C/C++ code I would like to include or not a file depending on different compilation.
For the moment I use this:
#ifndef __x86_64__
#include <myLib.h>
#endif
this gives me the possibility of doing whether the platform is 32/64 bit but does not give me enough freedom.
I would like to pass a variable to my makefile like
make includeMyLib=1
and depending on this having something like:
#ifndef includeMyLib
#include <myLib.h>
#endif
Do you know if anything like this is possible?
If you use GNU make, you could have something like this in the Makefile:
ifdef includeMyLib
CFLAGS += -DincludeMyLib
endif
This will change the flags used by the compiler to add the #define includeMyLib.

How to undefine a define at commandline using gcc

How do I at compile time undefine a compiler macro using gcc. I tried some compile args to gcc like -D but I can't get to see the "not defined" message.
Thanks
#include <iostream>
#define MYDEF
int main(){
#ifdef MYDEF
std::cout<<"defined\n";
#else
std::cout<<"not defined\n";
#endif
}
You can use the -U option with gcc, but it won't undefine a macro defined in your source code. As far as I know, there's no way to do that.
You should wrap the MYDEF definition in a preprocessor macro, the presence of which (defined on the command line) would then prevent MYDEF from being defined. A bit convoluted to be sure but you can then control the build in the way you want from the command line (or Makefile). Example:
#ifndef DONT_DEFINE_MYDEF
#define MYDEF
#endif
Then from the command line when you don't want MYDEF:
gcc -DDONT_DEFINE_MYDEF ...
http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Preprocessor-Options.html#Preprocessor-Options
The -U options seemed like what you could have needed... but then again you can't override a definition contained in your source code without resorting to more preprocessor directives.
You can resort to filtering source code and give this back to gcc for compilation, like this pseudo code:
grep -v "define MYDEF" yourFile.c | gcc -o yourFile.o -xc -
Hope it helps.
The code use case is not right. As I see, you have hard coded #define in the file. If compiler initially assumes MYDEF undefined, it will define it once it start processing the file.
You should remove the line #define MYDEF. And I hope your test case will work, if you pass MYDEF to -D and -U.
Here is one possibility that doesn't completely cover your use case but which I found to be helpful in my case.
If your MYDEF were #defined in a separate header file #included from the .c file you could force the definition of the #include guard macro with the -D option (thus preventing the MYDEF #definition) then either actively #define (still with the -D option) MYDEF to something else or just leave it undefined.
It is clear that anything else defined in the header file would also be missing but this was for me a solution to forcedly undefine a macro without changing the third-party code.

Resources