1

I want to define a macro as a string and later at compile time include code based on string comparison:

#include <iostream>
#include <string_view>

constexpr bool strings_equal(char const * a, char const * b) {
    return std::string_view(a)==b;
}

#define FOO "bar"


int main() {
#if strings_equal( FOO, "bar") == 0
    std::cout << "got a bar!" << '\n';
#endif
    return 0;
}

Compiling this with

$ g++ -std=c++17 test.cpp -o my_test

gives error:

test.cpp:12:18: error: missing binary operator before token "("
   12 | #if strings_equal( FOO, "bar") == 0
      |                  ^

Edit:

It appears that it matters if the #if directive is inside a function or not, since if it is inside a function we can replace it with if constexpr (...) { ... } But that is not possible if the #if is outside a function in the top level of a file.. and I forgot to mention that in my real code that is the case.

Håkon Hægland
  • 39,012
  • 21
  • 81
  • 174
  • 1
    This won't work - the preprocessor runs before the compiler. Static compile-time expressions are done by the compiler. – Sebastian Apr 04 '20 at 20:23
  • 2
    I don't think that's possible, since preprocessing happens before compilation and the preprocessor knows nothing about functions. – eesiraed Apr 04 '20 at 20:23
  • oh c'mon on. We are trying to go away from the preprocessor. `constexpr` is one step in this direction and you want to use it in the preprocessor (and for no good reason) – bolov Apr 04 '20 at 20:27
  • @bolov yes I know :) I forgot to mention that in my real code the `#if` directive is at the top level in another file (so it is not inside a function). Then `if constexpr () ` could not be used, right? – Håkon Hægland Apr 04 '20 at 20:30
  • So you would need a way to compare strings without constexpr, but just using the preprocessor? – Sebastian Apr 04 '20 at 20:33
  • @Sebastian Yes, I could not find that the preprocessor supported string comparison so I tried to use a `constexpr` function instead – Håkon Hægland Apr 04 '20 at 20:35
  • 4
    Maybe you can give some more details on the actual use case. Even if you can't use `if constexpr` there are other ways to branch on compile-time constants. – super Apr 04 '20 at 20:38
  • 1
    Some people in this long Stackoverflow QA were succesful comparing preprocessor string, depending on compiler and specific use case (any string comparison or out of a list):https://stackoverflow.com/questions/2335888/how-to-compare-strings-in-c-conditional-preprocessor-directives - alternatively you could think about using a makefile and doing the string comparison there – Sebastian Apr 04 '20 at 20:50

1 Answers1

7

This is not possible to do this way.

But you can use if constexpr like this.

#include <iostream>
#include <string_view>

constexpr bool strings_equal(char const * a, char const * b) {
    return std::string_view(a)==b;
}

constexpr auto FOO = "bar";

int main() {
    if constexpr (strings_equal( FOO, "bar")) {
        std::cout << "got a bar!" << '\n';
    }

    return 0;
}

Run-able Code

DevO
  • 365
  • 1
  • 8
  • I accept this answer even if it does not solve my real problem (see my updated question) since I forgot to mention that part in my question – Håkon Hægland Apr 04 '20 at 20:43