I am trying to figure out what version of Boost my code thinks it's using. I want to do something like this:
#error BOOST_VERSION
but the preprocessor does not expand BOOST_VERSION.
I know I could print it out at run-time from the program, and I know I could look at the output of the preprocessor to find the answer. I feel like having a way of doing this during compilation could be useful.
I know that this is a long time after the original query, but this may still be useful.
This can be done in GCC using the stringify operator "#", but it requires two additional stages to be defined first.
#define XSTR(x) STR(x)
#define STR(x) #x
The value of a macro can then be displayed with:
#pragma message "The value of ABC: " XSTR(ABC)
See: 3.4 Stringification in the gcc online documentation.
How it works:
The preprocessor understands quoted strings and handles them differently from normal text. String concatenation is an example of this special treatment. The message pragma requires an argument that is a quoted string. When there is more than one component to the argument then they must all be strings so that string concatenation can be applied. The preprocessor can never assume that an unquoted string should be treated as if it were quoted. If it did then:
#define ABC 123
int n = ABC;
would not compile.
Now consider:
#define ABC abc
#pragma message "The value of ABC is: " ABC
which is equivalent to
#pragma message "The value of ABC is: " abc
This causes a preprocessor warning because abc (unquoted) cannot be concatenated with the preceding string.
Now consider the preprocessor stringize (Which was once called stringification, the links in the documentation have been changed to reflect the revised terminology. (Both terms, incidentally, are equally detestable. The correct term is, of course, stringifaction. Be ready to update your links.)) operator. This acts only on the arguments of a macro and replaces the unexpanded argument with the argument enclosed in double quotes. Thus:
#define STR(x) #x
char *s1 = "abc";
char *s2 = STR(abc);
will assign identical values to s1 and s2. If you run gcc -E you can see this in the output. Perhaps STR would be better named something like ENQUOTE.
This solves the problem of putting quotes around an unquoted item, the problem now is that, if the argument is a macro, the macro will not be expanded. This is why the second macro is needed. XSTR expands its argument, then calls STR to put the expanded value into quotes.
BOOST_PP_STRINGIZE seems a excellent solution for C++, but not for regular C.
Here is my solution for GNU CPP:
/* Some test definition here */
#define DEFINED_BUT_NO_VALUE
#define DEFINED_INT 3
#define DEFINED_STR "ABC"
/* definition to expand macro then apply to pragma message */
#define VALUE_TO_STRING(x) #x
#define VALUE(x) VALUE_TO_STRING(x)
#define VAR_NAME_VALUE(var) #var "=" VALUE(var)
/* Some example here */
#pragma message(VAR_NAME_VALUE(NOT_DEFINED))
#pragma message(VAR_NAME_VALUE(DEFINED_BUT_NO_VALUE))
#pragma message(VAR_NAME_VALUE(DEFINED_INT))
#pragma message(VAR_NAME_VALUE(DEFINED_STR))
Above definitions result in:
test.c:10:9: note: #pragma message: NOT_DEFINED=NOT_DEFINED
test.c:11:9: note: #pragma message: DEFINED_BUT_NO_VALUE=
test.c:12:9: note: #pragma message: DEFINED_INT=3
test.c:13:9: note: #pragma message: DEFINED_STR="ABC"
For "defined as interger", "defined as string", and "defined but no value" variables , they work just fine. Only for "not defined" variable, they displayed exactly the same as original variable name. You have to used to it -- or maybe someone can provide a better solution.
If you are using Visual C++, you can use #pragma message:
#include <boost/preprocessor/stringize.hpp>
#pragma message("BOOST_VERSION=" BOOST_PP_STRINGIZE(BOOST_VERSION))
Edit: Thanks to LB for link
Apparently, the GCC equivalent is (not tested):
#pragma message "BOOST_VERSION=" BOOST_PP_STRINGIZE(BOOST_VERSION)
As far as I know '#error' only will print strings, in fact you don't even need to use quotes.
Have you tried writing various purposefully incorrect code using "BOOST_VERSION"? Perhaps something like "blah[BOOST_VERSION] = foo;" will tell you something like "string literal 1.2.1 cannot be used as an array address". It won't be a pretty error message, but at least it'll show you the relevant value. You can play around until you find a compile error that does tell you the value.
Without boost :
define same macro again and compiler HIMSELF will give warning.
From warning you can see location of the previous definition.
vi file of previous definition .
ambarish#axiom:~/cpp$ g++ shiftOper.cpp
shiftOper.cpp:7:1: warning: "LINUX_VERSION_CODE" redefined
shiftOper.cpp:6:1: warning: this is the location of the previous definition
#define LINUX_VERSION_CODE 265216
#define LINUX_VERSION_CODE 666
int main ()
{
}
In Microsoft C/C++, you can use the built-in _CRT_STRINGIZE() to print constants. Many of my stdafx.h files contain some combination of these:
#pragma message("_MSC_VER is " _CRT_STRINGIZE(_MSC_VER))
#pragma message("_MFC_VER is " _CRT_STRINGIZE(_MFC_VER))
#pragma message("_ATL_VER is " _CRT_STRINGIZE(_ATL_VER))
#pragma message("WINVER is " _CRT_STRINGIZE(WINVER))
#pragma message("_WIN32_WINNT is " _CRT_STRINGIZE(_WIN32_WINNT))
#pragma message("_WIN32_IE is " _CRT_STRINGIZE(_WIN32_IE))
#pragma message("NTDDI_VERSION is " _CRT_STRINGIZE(NTDDI_VERSION))
and outputs something like this:
_MSC_VER is 1915
_MFC_VER is 0x0E00
_ATL_VER is 0x0E00
WINVER is 0x0600
_WIN32_WINNT is 0x0600
_WIN32_IE is 0x0700
NTDDI_VERSION is 0x06000000
#define a <::BOOST_VERSION>
#include a
MSVC2015: fatal error C1083: Cannot open include file: '::106200': No such file or directory
Pros:
Works on builtin macroses
Works even if preprocess to file is enabled, even if invalid tokens are present:
#define a <::'*/`#>
#include a
MSVC2015: fatal error C1083: Cannot open include file: '::'*/`#': No such file or directory
GCC4.x: warning: missing terminating ' character [-Winvalid-pp-token]
#define a <::'*/`#>
Cons:
Sometime fails because of invalid characters in the include file path. Can be fixed by change a prefix (see update section below).
Update:
For GCC 4.7.x and lower the output throws the error:
error: #include expects "FILENAME" or <FILENAME>
To fix that you can change the prefix:
#define a <.__cplusplus>
#include a
fatal error: .201103L: No such file or directory
You could also preprocess the source file and see what the preprocessor value evaluates to.
You could write a program that prints out BOOST_VERSION and compile and run it as part of your build system. Otherwise, I think you're out of luck.
Are you looking for
#if BOOST_VERSION != "1.2"
#error "Bad version"
#endif
Not great if BOOST_VERSION is a string, like I've assumed, but there may also be individual integers defined for the major, minor and revision numbers.
Looking at the output of the preprocessor is the closest thing to the answer you ask for.
I know you've excluded that (and other ways), but I'm not sure why. You have a specific enough problem to solve, but you have not explained why any of the "normal" methods don't work well for you.
BOOST_VERSION is defined in the boost header file version.hpp.
Take a look at the Boost documentation as well, regarding how you are using the macro:
In reference to BOOST_VERSION, from http://www.boost.org/doc/libs/1_37_0/libs/config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.boost_helper_macros:
Describes the boost version number in
XXYYZZ format such that:
(BOOST_VERSION % 100) is the sub-minor
version, ((BOOST_VERSION / 100) %
1000) is the minor version, and
(BOOST_VERSION / 100000) is the major
version.
Instead of #error, try redefining the macro, just before it is being used. Compilation will fail and compiler will provide the current value it thinks applies to the macro.
#define BOOST_VERSION blah
Related
In my #include files, I want to output debug messages that include the line number and the script name, but while the #ScriptLineNumber macro emits the line number of the #include file it's in, there is no way to emit the current file's filename. I would like to define a user macro something like #ThisScriptName in a debug message like this:
_DebugOut("+++:" & #ThisScriptName & ":" & #ScriptLineNumber & ": some text")
The output would look something like this:
+++:SampleIncludedFile.au3:127: some text
There is no way to do this so that it gives the included file name using any of the macros available.
The easiest alternative method is to use a variable that is overwritten at the top of each include file.
ExampleScript.au3:
#include "ExampleInclude.au3"
Global $ThisScriptName = "ExampleScript"
ConsoleWrite("Hello From: " & $ThisScriptName & #LF)
ExampleInclude.au3:
; #include <...>
Global $ThisScriptName = "ExampleInclude"
ConsoleWrite("Hello From: " & $ThisScriptName & #LF)
With this approach it is important that the variable is defined after the other files you are including.
Other alternatives could be using a preprocessor, either writing one yourself or using one of the various ones others have written already. This could be as simple as just replacing every occurrence of #ThisScriptName with the string version of the file.
please excuse me if this question has already been answered elsewhere, but I'm not sure what to search for.
I am passing a value from a batch file, though a makefile, and to a header file, like so:
(Using AVR-GCC 4.5.2)
Batch:
make ADDR=FOO
Makefile:
CFLAGS += -DADDR=$(ADDR)
...
gcc $(CFLAGS) main.c
This is the header file main.h, included by main.c; it is supposed to select a specific pinout at compile-time, based on the value of ADDR:
#include "defs.h"
#if ADDR == FOO
... // Select pinout 1
#elif ADDR == BAR
... // Select pinout 2
#endif
The comparison values FOO and BAR are constants defined in a global header file defs.h included by main.h:
#define FOO 23
#define BAR 42
Now the problem: The comparisons don't work, ADDR constantly reads as 0. This seems to be because the preprocessor does not resolve ADDR before the comparison, i.e. expand FOO to 23. Telling the compiler to do this expansion would be helpful.
Of course it works if I pass ADDR=23 directly in the batch file, but for flexibility I want to use the aliases from defs.h instead of fixed numeric constants.
By the way, the following works if placed in main.c:
int addr_val = ADDR; // is now 23
Maybe there is a simple solution I am not aware of right now. Please feel free to contribute.
Have a nice day!
I am writing a module that allows users to log information. I want to provide an interface that logs a string message, which can be called as
call m_log(msg)
So in file m_logger.f90, I will have
module m_logger
..
subroutine m_log(msg)
..
end module
In file main.f90, a user will have
program main
use m_logger
call m_log(msg)
end program
Now how can I substitute call m_log(msg) with call m_log(msg, __FILE__, __LINE__) ?
Because of this substitution, a different subroutine subroutine m_log(msg, filename, linenum) in the logger module will be called instead.
If I use a macro like #define m_log(msg) m_log(msg,__FILE__,__LINE__) , it will have to be added to every user file that uses the logger.
Also, I do not want to enforce the user to pass __FILE__ and __LINE__ explicitly.
Is there a way I can do this? Or are there any other alternatives altogether?
Thanks in advance
Edit:
I had a discussion on comp.lang.fortran. Adding a link for reference.
here
In this case you would have to use the same approach C uses. Define the macro you proposed
#define log(msg) m_log(msg,__FILE__,__LINE__)
in a separate file (possibly with other useful macros) and include it using #include "file.inc" (standard Fortran include won't suffice).
If the macro has a different name, than the subroutine it actually calls, you can ensure that the user has to use the include and cannot forget it.
If you don't want to force __file__ and __line__ explicitly, then you can use the optional flag, such that your subroutine looks like:
subroutine m_log(msg, filename, linenum)
character(len=*) :: msg
character(len=*), optional :: filename
integer, optional :: linenum
if(present(filename)) then
<something with filename>
endif
if(present(linenum)) then
<something with linenume>
endif
<normal stuff with msg>
end subroutine
The intrinsic function present returns a true value if filename or linenum have any values attached to it, returning false otherwise.
Since you want them to be passed as compiler macros by the user, you would first have to choose different names for your macros. __FILE__ and __LINE__ are both predefined macros. These two macros are defined by preprocessor, not passed by the user. I think that might have cause some confusion.
If you would like to allow users to optionally supply the macros through compiler options, it is probably best to include #ifdef directive in your subroutine:
subroutine m_log(msg)
implicit none
character(len=*) :: msg
character(len=something) :: file
integer ::line
!Initialize file and line to some default value
file=...
line=...
#ifdef __KVM_FILE__
file=__KVM_FILE__
#endif
#ifdef __KVM_LINE__
line=__KVM_LINE__
#endif
...
This way the user will always call the subroutine with the same syntax call m_log(something), but the effect will change according to your compilation macros. Of course, that would also require the user to recompile your code every time they change this macro. If this is too costly to do, you can set up a subroutine with optional argument (as in Kyle's answer), then enclose #define macro in #ifdef blocks, and put them into an .h file, and have your user always include that file. (similar to Vladimir's answer)
I have a simple code in lex language and i generate lex.yy.c with Flex.
when i want to compile lex.yy.c to .exe file i get some error like "undeclared (first use in this function) " ! when i search in web i understand i need a Const.h file, so i want to generate that file.
how i can do this ?
Some Errors:
35 C:\Users\Majid\Desktop\win\lex.l STRING' undeclared (first use in this function)
38 C:\Users\Majid\Desktop\win\lex.lLC' undeclared (first use in this function)
39 C:\Users\Majid\Desktop\win\lex.l `LP' undeclared (first use in this function)
....
Beginnig of The Code is :
%{int stk[20],stk1[20];
int lbl=0,wlbl=0;
int lineno=0;
int pcount=1;
int lcount=0,wlcount=0;
int token=100;
int dtype=0;
int count=0;
int fexe=0;
char c,str[20],str1[10],idename[10];
char a[100];
void eatcom();
void eatWS();
int set(int);
void check(char);
void checkop();
int chfunction(char *);%}
Digit [0-9]
Letter [a-zA-Z]
ID {letter}({letter}|{digit})*
NUM {digit}+
Delim [ \t]
A [A-Za-z]]
%%
"/*" eatcom();
"//"(.)*
\"(\\.|[^\"])*\" return (STRING);
\"(\\.|[^\"])*\n printf("Adding missing \" to sting constant");
"{" {a[count++]='{';fexe=0;eatWS();return LC;}
"(" {a[count++]='(';eatWS();return LP;}
"[" {a[count++]='[';eatWS();return LB;}
"}" {check('{');eatWS();
if(cflag)
{
//stk[lbl++]=lcount++;
fprintf(fc,"lbl%d:\n",stk[--lbl]);
//stk[lbl++]=lcount++;
printf("%d\n",stk[lbl]);
cflag=0;
}
return RC;
}
"]" {check('[');eatWS();return RB;}
")" {check('(');eatWS();return RP;}
"++" | "--" return INCOP;
[~!] return UNOP;
"*" {eatWS();return STAR;}
[/%] {eatWS();return DIVOP;}
"+" {eatWS();return PLUS;}
"-" {eatWS();return MINUS;}
You need a .h file with the definitions. You can write it by hand, but typically this file is generated by Bison. The two tools Flex and Bison are very often used together.
Bison is a parser-generator. Its input is a file where you have written a grammar that describes the syntax of a language, and Bison generates a parser. The parser (or "syntactical analyzer") is the part of a compiler (or similar tool) that analyzes input according to the syntax of the language. For example, it is the parser that knows that an if statement can, but doesn't have to, have an else part.
Flex is a scanner-generator, and from a file with regular expressions it creates a scanner. The scanner (or "lexical analyzer") is the part of a compiler (or similar tool) that analyzes input and divides it up into "tokens". A token can be a keyword such as if, an operator such as +, an integer constant, etcetera. It is the scanner that for example knows that an integer constant is written as a sequence of one or more digits.
The scanner reports to the parser when it has found a token. For example, if the input starts with 123, the scanner might recognize that this is an integer constant, and report this to the parser. In the case of Flex and Bison, it does this by returning the token code for integer constant, which might (just as an example) be 17. But since the scanner and parser must agree on these token codes, they need common definitions. Bison will generate token codes, and if given the flag -d it will output them in a .h file.
Thomas Niemann's A Compact Guide to Lex & Yacc gives a good introduction to how to use Flex and Bison. (Lex and Yacc are the old, original tools, and Flex and Bison are new, free versions of the same tools.)
For yacc and lex part this error disappeared for me when I used yacc -d xyz.y command where d is flag and xyz is file of my yacc file.
I have some debugging code that looks like the following:
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
void __my_error(const char*loc, const char *fmt, ...);
#define my_error(fmt, ...) __my_error(AT, fmt, ##__VA_ARGS__)
The last macro is used so I can insert the location into the debug output as to where the error occurred. However, when I call the function like this:
my_error("Uh oh!");
I would like my code to be C99, so I find when this compiles, I get the following error:
error: ISO C99 requires rest arguments to be used
I know I can solve this by changing the call to
my_error("Uh oh!", NULL);
But is there any way to make this look less ugly? Thanks!
I see two solutions to this problem. (Three if you count 'stick with gcc').
Extra special case macro
Add a new macro for when you want to print a fixed string.
#define my_errorf(str) my_error(str, NULL)
Pro: Minimum amount of extra code.
Con: It's easy to use the wrong macro (but at least you notice this at compile time).
Put fmt inside the '...'
Vararg macro's can have only __VA_ARGS__ as parameter (unlike vararg functions). So you can put the fmt argument inside the __VA_ARGS__ and change your function.
void __my_error(const char *loc, ...);
#define my_error(...) __my_error(AT, __VA_ARGS__)
Pro: One syntax/macro for all error messages.
Con: Requires rewriting of your __my_error function, which might not be possible.