Compilation time message (after preprocessor) to use with `if constexpr`
Asked Answered
A

1

8

I am using an if constexpr to test the presence of a method in a class. If the method is not present, I wish to tell the user the function was ignored and he should implement it but it is not mandatory.

The idea is to give a message similar to #warning but the preprocessor is processed before the template thus this will never work.

Is there any compilation time feedback alternative that came with C++17? Or any planned for C++20?

Runnable example

template <typename State>
void callStateFunction(const State& state) {
  if constexpr (false) {
    state.method();
  } else {
    #warning The method State::method() was not implemented
  }
}
Amersham answered 10/7, 2020 at 16:29 Comment(1)
I know that it doesn't do exactly what you want to do but have you considered using static_assert()? This would generate an error rather than a warning, though. Generating a warning for code that is correct is probably a bad idea in the first place...Pastoralist
C
1

Not a great solution, I suppose, but...

If your compiler activate all warnings (-Wall for g++ and clang++, by example), you can substitute the #warning row with something that generate a warning.

By example, an unused (maybe with a talking name) variable.

I've tried with

template <typename State>
void callStateFunction(const State& state) {
  if constexpr (false) {
    state.method();
  } else {
    int method_not_implemented[sizeof(State)];
  }
}

and calling with a non-method value (callStateFunction(1), by example), I get

prog.cc: In instantiation of 'void callStateFunction(const State&) [with State = int]':
prog.cc:13:23:   required from here
prog.cc:7:9: warning: unused variable 'method_not_implemented' [-Wunused-variable]
    7 |     int method_not_implemented[sizeof(State)];
      |         ^~~~~~~~~~~~~~~~~~~~~~

from g++ (head 11.0.0) and

prog.cc:7:9: warning: unused variable 'method_not_implemented' [-Wunused-variable]
    int method_not_implemented[sizeof(State)];
        ^
prog.cc:13:4: note: in instantiation of function template specialization 'callStateFunction<int>' requested here
   callStateFunction(1);
   ^

from clang++ (head 11.0.0)

I suggest that the unused variable depends from the template typename (State) otherwise, if I define a non-dependent variable as

int method_not_implement;

I get a warning from clang++

prog.cc:7:9: warning: unused variable 'method_not_implemented' [-Wunused-variable]
    int method_not_implemented;
        ^

also without calling the function with a non-method object.

Cockatiel answered 10/7, 2020 at 17:29 Comment(5)
Neat hack, but not something I'd want to rely on...Guffaw
Not ideal, but this is pretty close. Maybe use some code that triggers warnings on all compilers, even with no warnings enabled. (If such code exists).Forward
@JesperJuhl - I'm agree... unfortunately I can't imagine something that is very reliable.Cockatiel
@Forward - Not enabling warnings, I fear you can count only in errors, but the OP explicitly want only a warning. Unfortunately I'm agree with Jesper Juhl: not a reliable solution: seems to work with g++ and clang++ but we're not sure that works with every compiler.Cockatiel
I wished there was an alternative in the actual C++ specs due to the new compile-time capability of the language. Sadly, this will not link the error to the actual method non implemented. I believe I should remove the compile-time check and enforce all functions to be implemented, and relying on the error which points to the State implementation: main.cpp:9:11: error: ‘const class State’ has no member named ‘method’ while being templated.Amersham

© 2022 - 2024 — McMap. All rights reserved.