-1

I have some C++ code compiling depending on some #define. Today I mistakenly forgot to #include the file with the defined, which lead to my program being compiled with the wrong code.

What are my options to get rid of this potential error?

mauro
  • 69
  • 1
  • 5
  • 2
    Refactor your code not to need it? It's a little hard to answer such a broad question in another way. – Some programmer dude Oct 19 '18 at 13:57
  • It really depends on what they are doing. Without seeing the code there isn't much concrete advice we can give you. – NathanOliver Oct 19 '18 at 13:57
  • "One issue i got today is i forgot to add the file" you cannot forget to add a file when you work with C++, you can easily get UB. – Slava Oct 19 '18 at 14:09
  • OP, your question was unclear but I think I got it anyway. I've edited it. If you think it is no better, you can rollback your question to what it was. – YSC Oct 19 '18 at 14:10

2 Answers2

5

Most compilers let you define preprocessor macros within the compilation command line. For instance, g++ and clang++ have -DMACRO=VALUE.

trunit.cpp:

#include <iostream>

int main() {
    #ifdef ALT_FOO
        std::cout << "BAR\n";
    #else
        std::cout << "FOO\n";
    #endif // ALT_FOO
}

In the current situation you're in, this code's behaviour would depend on the inclusion of a header file defining or not the macro ALT_FOO. You can control that from the build process itself:

$ # build the FOO variant:
$ g++ -Wall -Wextra -Werror -pedantic -O2 trunit.cpp -o foo
$ ./foo
FOO

$ # build the BARvariant:
$ g++ -Wall -Wextra -Werror -pedantic -O2 -DALT_FOO trunit.cpp -o foo
$ ./foo
BAR
YSC
  • 38,212
  • 9
  • 96
  • 149
2

Have the macro header either #define FOO or #define NFOO.

You would then test for exactly one of FOO or NFOO to be defined

#if defined(FOO) && defined(NFOO)
#error both FOO and NFOO defined
#elif defined (FOO) 
    // foo case
#elif defined (NFOO) 
    // not foo case
#else
#error neither FOO nor NFOO defined
#end
Caleth
  • 52,200
  • 2
  • 44
  • 75
  • I like this solution better as it does not pollute with define the compiler command. But on this base I though it could became much better using values; a non-define var is 0, so then 1 may be "defined" and 2 "undefined" and avoid the issue of double declarations: #lif defined (FOO == 1) // foo case #elif defined (FOO == 2) // not foo case #else #error FOO not defined #end – mauro Oct 29 '18 at 12:27
  • @mauro if `FOO` is not defined, it is neither `0`, `1`, or `2`. You'd have to `#if defined(FOO) #if FOO == 1 ... #elif FOO == 2 ... #else #error unknown FOO #end #else #error missing FOO #end`, which is also rather verbose – Caleth Oct 29 '18 at 12:33
  • the standard explicitly say "remaining identifier" are set to 0, see https://stackoverflow.com/questions/5085392/what-is-the-value-of-an-undefined-constant-used-in-if – mauro Oct 29 '18 at 15:02