How to pass and use arguments in ./configure? - assert

I would like to be able pass arguments to ./configure script, so it would add NDEBUG used by to my generated header file. How can I do that? My configure script is generated from configure.ac.
I already one great answer, but it seems that I my question is wrong. The option would have to remove this NDEBUG, because by default I would like to have assertions turned off. There is no AC_UNDEFINE, so I need to use some trick: define ASSERT_ON, which would turn off NDEBUG. Is there any easier, better way?

You'll want to use the AC_ARG_ENABLE() macro in your configure.ac file to trigger an action when someone adds --enable-foo to your command line options.
AC_ARG_ENABLE(foo, "used to turn on the NDEBUG flag",
[ AC_DEFINE(NDEBUG) ]
)

You can use AH_VERBATIM in order to add extra data to your config.h.in (and thus, config.h file).
The thing is, autoconf is going to comment out anything that looks like a #undef statement when producing the config.h file out of the template.
There is a preprocessor trick to avoid that: use #/**/undef/**/. The C preprocessor is going to strip the comments first, but autoconf will not see that as a #undef statement.
To recap, in order to enforce NDEBUG being undefined:
AH_VERBATIM([NDEBUG], [/* Never ever ignore assertions */
#ifdef NDEBUG
#/**/undef/**/ NDEBUG
#endif])

Related

Using a macro to define an include file

To make a long story short, I'm working on some code that needs different header files based on various configuration options. I could do something like this:
#if OPTION == A
#include "relative/path/to/file/a.hpp"
#elseif OPTION == B
#include "relative/path/to/file/b.hpp"
#elseif OPTION = ...
...
#endif
This would work, but it seems like a really ugly solution for what could potentially be more than a handful files. I could also simply include all the various header files, but that, too, seems like a bit of an ugly solution, and it could pose problems in the future if files (for some horrible reason) start redefining the same objects. The idea I had was that something like the following would be nice, particularly in the context of how the rest of the code is written:
#define QUOTE(str) #str
#define STRINGIFY(A,B) QUOTE(A##B)
...
#include STRINGIFY(relative/path/to/option/,OPTION)
The problem with this seems to be two-fold:
The OPTION definition doesn't expand properly inside STRINGIFY.
If there are any forward slashes in the path name, STRINGIFY fails altogether, with g++ giving me an error along the lines of the following:
error: pasting "/" and "OPTION" does not give a valid preprocessing token
I can't seem to find any real information on why / is a bad character for the C++ preprocessor, just a few articles saying that you should just put "/" in and rely on automatic C++ string concatenation (which doesn't work in an #include statement). I'm willing to consider design alternatives if I'm just trying to do something really dumb, but I'd also like to figure out why this isn't working.
EDIT: I should make the clarification that I'm working on a codebase originally designed by a group of scientists. Reasonable coding conventions and typical expectations for how a code gets used go completely out the window. This code will probably be modified at least as many times as it gets used, often by people who have spent their entire careers writing Fortran 77 and think object-oriented programming is some new-fangled invention that just makes your code harder to understand.
When writing macros it is essential to look at the output after preprocessing. With gcc thats the -E option.
To include different files I would rely on your build tools rather than macro voodoo. For example when the code is
include option
Then gcc -E -option=\"foo.h\" yields
include "foo.h"
Note that I ommitted the # here, otherwise preprocessing would fail due to not finding "foo.h".
I wanted to do something similar, searched around and found this post, and after trying few things I think I can help you.
So, your approach:
#define QUOTE(str) #str
#define STRINGIFY(A,B) QUOTE(A##B)
...
#include STRINGIFY(relative/path/to/option/,OPTION)
As I understand from https://gcc.gnu.org/onlinedocs/cpp/Concatenation.html doesn't work because when using ## to paste tokens, the result must be a valid token, where something like path/to/file.hpp is not a valid preprocessing token.
Now, I think that you only need to have a macro which holds the path plus the token to be replaced. Well, you don't really need to add the relative path if you are using the -I flag. Your macro could look like #define myMacro relative/path/to/file/OPTION.hpp, then you just need to define OPTION and pass it to one macro so OPTION gets replaced with its value and then another macro to stringize. These two levels of macros are described here https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html#Stringizing
The following example will ilustrate both cases (with/without -I flag).
Consider this directory structure:
.
|-- a.c
|-- headers
| |-- A.hpp
| `-- B.hpp
`-- makefile
Where a.c:
#define header OPTION.hpp
#define xstr(x) #x
#define str(x) xstr(x)
#include str(header)
makefile:
PATH_OPTION ?= headers/A
OPTION ?= A
.PHONY: all
all: a.c
cpp -D OPTION=${PATH_OPTION} $<
cpp -I./headers -D OPTION=${OPTION} $<
A.hpp
#warning Including A.hpp
1
B.hpp
#warning Including B.hpp
2
With this, you can call make which by default will include headers/A.hpp and you should be able to see both approaches (with/without -I flag) working and printing to stdout the corresponding warning.
To include headers/B.hpp you would do make OPTION=B or make PATH_OPTION=headers/B depending on the approach you take.
I also tried with g++ instead of cpp and it works as well.

Is the _HAVE_BOOST macro a built-in in C++? Where does it come from?

I'm reading a piece of code that seems like it optionally uses the C++ Boost library. It is as follows:
#ifdef _HAVE_BOOST
#include <boost/random.hpp>
#endif
Later on in the code, there are several statements that depend on this "_HAVE_BOOST". I presume that _HAVE_BOOST is simply a flag that is set to true, if the C++ library is properly imported.
Is the "_HAVE_BOOST" flag a built-in part of C++ ifdef syntax? That is, I tried Googling for this flag but didn't find any documentation. Also, at the head of the file, no #include<boost> is present. It looks like this boost functionality is deprecated throughout the file -- would _HAVE_BOOST be set to true if this #include<boost> were added?
Is there a list or documentation somewhere for describing the kinds of capital letters that go along with #ifdef?
I presume that _HAVE_BOOST is simply a flag that is set to true...
#ifdef _HAVE_BOOST does not test whether _HAVE_BOOST is true; It test whether such preprocessor macro is defined at all, regardless of the value.
...if the C++ library is properly imported.
Yes, considering the context, this particular macro is probably meant to signify, whether Boost is available or not and thus, whether it's possible to depend on it.
Is there a list or documentation somewhere for describing the kinds of capital letters that go along with #ifdef?
Macros can be defined with either #define directive in a header file or, in the compilation command (See the -D option for gcc for example). Compilers may also predefine some macros as well.
Any header file can define macros. You should usually be able to find which macros may be defined by reading the documentation, or if you don't have documentation, by reading the header files themselves.
would _HAVE_BOOST be set to true if this #include were added?
I find it unlikely that it would be defined in <boost> itself. After all, testing if Boost is available after you try to include it would be rather pointless.
When is _HAVE_BOOST defined?
You should ask that from the person who wrote the code. Another question to ponder is, is it defined at all? If it isn't, then the code between the ifdefs is removed by the preprocessor.
My crystal ball tells me that it's probably supposed to be defined by some sort of configuration script for the build process. For example, autoconf has a macro that will define a preprocessor macro HAVE_header-file if a header exists. Note the lack of underscore at the beginning.
this just means that if you define a preprocessor macro "_HAVE_BOOST" the compiler will include boost/random.hpp. Like this:
#define _HAVE_BOOST
#ifdef _HAVE_BOOST
#include <boost/random.hpp>
#endif
Look here for more details about preprocessor directives.
If the compiler supports c++11, it will have <random> support.
With some clever use of indirect includes and typedefs (or using statements ?!) it could be made to work with or without boost for random.

Avoid macro to be usable from client code

I'm currently working on a header only library and I'd like to be able to use some macros without them being usable from client code. Example:
// library_header1.h
#define MACRO_NUMBER_1(__X__) doSomethingWith(__X__) // etc...
class LibraryClass1
{
// We'll use the macro somewhere in here.
};
Now, if I include library_header1.h i'm able to use MACRO_NUMBER_1. Is there any way I can avoid that?
Others already mentioned #undef but what if you have many macros you need to undefine and you need to use them in many headers? This situation can be dealt with by having a header define and undefine macros and bewteen that include a specified header. For example:
// temp-macros.h
#if defined(OUTER)
# define MACRO x
# include OUTER
# undef MACRO
# undef OUTER
#endif
The idea is to set up OUTER from the header where the macros are neede, include temp-macros.h and use the macros in the second inclusion:
// macro-use.h
#if !defined(OUTER)
# define OUTER "macro-use.h"
# include "temp-macros.h"
#elif !defined(INCLUDED_MACRO_USE)
# define INCLUDED_MACRO_USE
void use(int MACRO) { /*...*/ }
#endif
Of course, this example uses just one trivial macro but if there are more macros and they are more complicated this approach could be useful.
To prevent the library user from accessing the macro - you can put #undef when you know you won't need your macro anymore.
If you want to prevent intellisense/autocompletion from ever seeing your macro, you may try to trick it by skipping it over the macro definition. Usually you can do it as follows:
set up your compilation project (visual solution, makefile, ...) so that you pass an extra "identification" macro. Something like -DIAMCOMPILING
Guard your macro definition with #ifdef IAMCOMPILING ... #endif
your IDE will most likely not recognise IAMCOMPILING and skip over the definition of your macro.
Do note however, that then IDE will get confused when your actually use the macro in the header file and some nonexistent errors will be flagged.
Whilst it won't stop the macro from being noticed by the IDE, if you use a unusual prefix to the macro, it will be less likely to collide with something that the user will want to do, and thus be less offensive. It may not be the ideal solution, but prefixing the macro with CCC or XWX or something else that is unlikely to be used by the normal programmer may help.
(Or, don't use macros is always a solution that works!)

How to suppress #define locally?

Just caught a silly bug. I have a zip processing library with a CreateFile() function in it. Winbase.h, included somewhere deep in my headers, redefines it as CreateFileW and linker goes nuts.
Of course I will exclude winbase in this particular case. It just shouldn't be in the scope in the first place. But the theoretical question is still interesting,
Is there a way to suppress some defines locally?
You can get around the macro by putting parentheses around the name:
(CreateFile)(arguments);
This works because the macro CreateFile is a function-like macro (i.e. it takes a list of arguments in parentheses); the right parenthesis after the name doesn't match the syntax for using a function-like macro, so the preprocessor does not expand it.
Of course, the "right" solution is to name the function properly, i.e., create_file. <g>
Removing the offending header file is ALWAYS the best solution for this (especially one as large as windows.h or winbase.h - they are included far too freely for my taste in many projects).
The only other solution is #undef offending_symbol.
Of course, another important thing is "do not use names that match the Windows/Linux system call names" - but CreateFile is a very obvious name for a function that creates a file, so I can see the temptation.
Preprocessor macros have no notion of C++ scope. #defines are just text replacements. If you want to have a 'local' #define, you do something like this:
#define CreateFileW CreateFile
... // here I can use the macro
#undef CreateFileW
Or in your case
#undef CreateFileW
... // Here the macro is not available
#define CreateFileW CreateFile
There is
#undef
which removes defines (but nothing else).
Apart from the aforementioned #undef there technically is not much you can do against #defines, at least not portably.
The best way is to not use #define at all, or at least as little as possible and as constrained as possible. Sometimes you just need a macro to generate some boilerplate code a few times. Be sure to #undef that macro once you are done. The only other valid applications of #define I can think of are include guards and flags for conditional preprocessing.
For #define-deseases like the WinAPI headers you just should constrain them as much as possible. Don't use the #defined types of that API in your headers. You almost never want to use an API all over your application, so use it only in the cpps of a small layer around the API. Reducing the dependencies that way gives a lot more than just disinfecting the rest of your code.

Tool/Parser for preprocessor #if statements?

I am working on many C-sourcecode files which contain many preprocessor #if, #elseif and #else statements.
This statements often check for a #define, e.g.
#if(Switch_TestMode == Switch_TestModeON)
/* code 1 */
#else
/*code 2 */
#endif
Often this preprocessor statements are located within c-if statements which makes the sourcecode nearly unreadable for human beeings.
The #defines used for this preprocessor #if statements are defined within an extra file.
My idea now is to have a tool which checks this #defined switch settings and then only copies the lines of sourcecode which apply using the current #defines/switch settings.
For the above example I would like to get a new .c file which contains only
/*code 2 */
assumed the #define of Switch_TestMode is not equal to Switch_TestModeON.
Are there tools (freeware || low-cost) available which do this job?
Or do I have to write my own preprocessor parser for this?
(It is impossible for me to run the compiler using a special parameter which does this job, because our company is creating the C-sourcecode, another company is compiling.)
Thanks for any hint!
Regards
Thomas
unifdef is available from http://dotat.at/prog/unifdef/.
Try Sunifdef
Edit: Which has now become Coan
You can run the GNU compiler using command line option -E to do the preprocessing.
http://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html
You can use unifdef.