22

Is there a way to make static_assert's string being dynamically customized and then displayed?
What I mean is something like:

//pseudo code
static_assert(Check_Range<T>::value, "Value of " + typeof(T) + " type is not so good ;)");
Luc Danton
  • 34,649
  • 6
  • 70
  • 114
smallB
  • 16,662
  • 33
  • 107
  • 151

3 Answers3

12

No, there is not.

However this does not matter so much, because static_assert are evaluated at compile-time, and in case of error the compiler will not only print out the message itself, but it will also print the instanciation stack (in case of templates).

Have a look at this synthetic example in ideone:

#include <iostream>

template <typename T>
struct IsInteger { static bool const value = false; };

template <>
struct IsInteger<int> { static bool const value = true; };

template <typename T>
void DoSomething(T t) {
  static_assert(IsInteger<T>::value, // 11
  "not an integer");

  std::cout << t;
}

int main() {
  DoSomething("Hello, World!"); // 18
}

The compiler does not only emits the diagnostic, but it also emits the full stack:

prog.cpp: In function 'void DoSomething(T) [with T = const char*]':
prog.cpp:18:30:   instantiated from here
prog.cpp:11:3: error: static assertion failed: "not an integer"

If you know Python or Java and how they print the stack in case of exception, it should be familiar. In fact, though, it's even better, because you not only get the call stack, but you also get the arguments values (types here)!

Therefore, dynamic messages are not as necessary :)

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • 1
    Thanks for your answer, although I see the point you're trying to make I'm still convinced that it would be quite nice to be able to customize what static_assert outputs. – smallB Oct 15 '11 at 18:00
  • 1
    @smallB: I suppose it would, however there is no real string manipulation at compile-time. The preprocessor has *some limited* magic (like turning a token into a string) and there is (at some point) the merging of adjacent string literals, but the truth of the matter is that C++ sorely lack true compile-time string manipulation, and it is reflected here :x – Matthieu M. Oct 16 '11 at 11:20
  • Sometimes you want to make ABI assertions about things like, e.g., type size, and on failure it is extremely useful to know what the actual mismatched value was. – Conrad Meyer Nov 08 '19 at 21:20
10

The standard specifies the second argument of static_assert to be a string literal, so no chance for computation there as far as I can see (except for preprocessor macros).

A compiler could extend the standard and allow const-expressions of approporiate type in this position, but I have no idea if any compiler does.

Patrick
  • 3,790
  • 1
  • 16
  • 12
  • 2
    Doesn't look like `constexpr` helps either: https://godbolt.org/g/Fb4WfF It appears the standard specifically requires a `string-literal` for whatever reason: See [page 155](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf) – Teh JoE Dec 12 '17 at 14:22
  • Yeah I put substantial effort into that... www.rkine.com/c-compile-time-string-literal-concatenation/ I could get literals to concatenate... but they are no longer "string-literal". – David Ledger Nov 14 '18 at 13:08
8

As Matthieu said, it's not possible, but you can get some of the functionalities you're looking for by using macros:

#define CHECK_TYPE_RANGE(type)\
    static_assert(Check_Range<type>::value, "Value of " #type " type is not so good ;)");

CHECK_TYPE_RANGE(float); // outputs "Value of float type is not so good ;)"
OLP
  • 803
  • 8
  • 10