12

I have been trying to implement a method similar to static_assert which is defined in the C++11 standard. The main problem is how does the C++ compiler write the text message being passed to static_assert as a const char*? I can get the compiler to write a message like A_is_not_POD. This is what I have:

#define MY_STATIC_ASSERT(condition, name)         \
   typedef char name[(condition) ? 1 : -1]; 

But it would be quite nice to get the compiler to write something like "Error: A is not POD." Any suggestions?

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
Shubham
  • 352
  • 3
  • 14
  • 1
    No that's not possible. The only thing you can get with older standards, is to spit out variable names. – πάντα ῥεῖ Dec 06 '13 at 14:12
  • 1
    “I can get the compiler to write a message like A_is_not_POD” How about showing what you have already done to achieve that? It would make your question clearer. The FAQ used to say “the best questions have a bit of source code in them” before it was re-revamped. – Pascal Cuoq Dec 06 '13 at 14:14
  • That's a shame. But where can we find the source code of static_assert function? The interesting thing is how does the compiler write the string to the compiler message. I have been trying to use templates somehow but have been unsuccessful so far. – Shubham Dec 06 '13 at 14:14
  • 4
    @Shubham C++11's `static_assert` is not a function - it's a keyword, just like `for`. There's no source code for `for` either. That's why the compiler can do anything it really wants with the arguments. – Angew is no longer proud of SO Dec 06 '13 at 14:17
  • I would guess it's impossible, since Boost's static assert can't print messages in C++03. Presumably, they tried pretty hard to find a way; and if it's impossible in C++03, it's almost certainly impossible in C99. – Mike Seymour Dec 06 '13 at 14:51
  • There are certainly ways to get nice error messages in C99. The easiest is to use [Clang](http://clang.llvm.org) as your compiler. What compiler are you trying to get this to work on? (No portable solution exists, because the C Standard doesn't have any concept of "printing messages at compile time".) – Quuxplusone Dec 07 '13 at 01:48

2 Answers2

6

Not sure i understand question, but C11 have _Static_assert(condition, errmessage). In C99 this functionality was missing but, depending on compiler, it could be possible to emulate. E.g. for gcc (unfortulately clang doesn't support attribute(error))

#define MY_STATIC_ASSERT(cnd, descr) ({ \
    extern int __attribute__ ((error("static assert failed: (" #cnd ") (" #descr ")"))) \
               compile_time_check(void); \
    ((cnd) ? 0 : compile_time_check()), 0; \
})
keltar
  • 17,711
  • 2
  • 37
  • 42
  • That's really nice. I didn't know we could do something like this!!! Its a shame clang doesn't provide this feature. Will however, will have a look around. Thanks a lot!!! – Shubham Dec 08 '13 at 14:58
3

In the c99 standard there is no "official" way to perform a static assertion in your C++ compiler.

"The main problem is how does the C++ compiler write the text message being passed to static_assert as a const char*?"

The C++ compiler detects an error in the code and prints out an appropriate error message based on a standard list of messages it has for each error that is known it can encounter. In c99, the compiler doesn't know what a "static assert error" is, so you need to cause some other error.

However, because creating static asserts with a c99 compiler is kind of a hack, it is not capable of printing out a nice error message exactly how you want.

For your example,

#define MY_STATIC_ASSERT(condition, name)         \
    typedef char name[(condition) ? 1 : -1];
MY_STATIC_ASSERT(false, my_error_msg)

will trigger the "error: size of array ‘my_error_msg’ is negative" message in the gcc compiler (and should a similar message in other compilers, you hope!). Giving the array an error message for the name was a way to print out your own info. There are various other techniques/hacks you can do on purpose such as bad templates, enums link

Note: you can provide custom compiler messages prior to C++11 using pre-processor macros such as #error or #pragma. However pre-process time is not the same as compile-time! The the pre-processor has a limited ability to evaluate many expressions and keywords such as "if", "sizeof", "return" and so on have no meaning to the pre-processor, only the compiler. link with some overview

Community
  • 1
  • 1
Jacqui Gurto
  • 1,496
  • 1
  • 10
  • 4