2

On a C++ project I got an idea to mix some compile time macro with std::optional to do something like :

#include <optional>

struct Foobar
{
    std::optional<int> foo;
    std::optional<int> bar;
};

int main()
{
    Foobar foobar;
    #ifndef DISABLE_FOO
    foobar.foo = 42;
    #endif // DISABLE_FOO
    #ifndef DISABLE_BAR
    foobar.bar = 24;
    #endif // DISABLE_BAR

    //later in the code

    if (foobar.foo.has_value())
    {
        //do some stuff with foo
    }
    if (foobar.bar.has_value())
    {
        //do some stuff with bar
    }
}

Ideally foo and bar would not be int but more complex structures. This would ease the readability by not having to use #ifndef everywhere but for me transforming compile time conditions in runtime conditions like that feels wrong. Could this be considered bad design (and if yes why?).

blunova
  • 388
  • 1
  • 4
  • 16
f222
  • 1,020
  • 6
  • 17
  • I would ask if there is a particular reason you're doing this. If these variables are set only at compile time, then the `if` statements they modify could also just be modified at compile time and potentially save your program a jump, which may matter if the code is performance critical. If the values are modified elsewhere then I have to wonder why the initial values should be different at compile time at all. – Turksarama Nov 29 '21 at 22:50
  • You end up with a bunch of code that never gets executed, and some extra overhead accessing `foo` and `bar`. – 1201ProgramAlarm Nov 30 '21 at 00:55
  • 1
    I mean, it's not the *worst* idea assuming the compiler directives are limited to one or two places. If this is just to disable certain functionality it might be better to use command line arguments. – JMekker Nov 30 '21 at 01:32

2 Answers2

1

Forget about compile time and runtime (mostly). There will be situations where you detect at runtime that functionality should not be used. What you should check for:

If possible at all, use a flag for functionality, not for a variable which is purely for your implementation.

And if at all possible, make it hard to use foo and bar by accident when they should not be used. That will depend on your language.

gnasher729
  • 42,090
  • 4
  • 59
  • 119
0

There will be a module M in your code which has functionality which is controlled by a runtime flag. Let us assume this is designed well, and there are no such reasons like performance issues which stand against it.

Then, there will be another part in your code which initializes this runtime flag. How this happens precisely should not be M's concern. This is called orthogonality, and it is often a sign of good design. So whether the initialization is controlled by a runtime or a compile time condition, or a mixture of both, or sometimes the former and sometimes the latter, should simply not matter from M's perspective.

If it does, that would IMHO be a design smell.

Doc Brown
  • 199,015
  • 33
  • 367
  • 565