3

I have some rather costly static_assert calls scattered throughout my code. While these are valuable, they are often superfulous and significantly contribute to compile time and memory usage.

Can I disable them?

quant
  • 21,507
  • 32
  • 115
  • 211
  • 1
    Yes. By removing them. – Rapptz Oct 30 '14 at 01:52
  • @Rapptz How would I re-enable them? – quant Oct 30 '14 at 01:54
  • 1
    Are you sure these `static_assert` calls are responsible for all that overhead? – Brian Bi Oct 30 '14 at 01:54
  • @Brian not all of it, but many of them include non-trivial meta-functions that contribute substantially and aren't needed for all builds. – quant Oct 30 '14 at 01:55
  • 1
    The only way to disable `static_assert`s is by removing them from the code which will be compiled, for example by using the preprocessor. They do not in any way contribute to the compiled code. – Deduplicator Oct 30 '14 at 01:56
  • On a somewhat 'meta' note. You should really start accepting answers. Your past 20 or so questions have no accepted answers. That's typically looked down upon here. – Rapptz Oct 30 '14 at 21:15
  • @Rapptz I tend to wait until I either receive a perfect answer or until I'm confident the answer is as good as what can be done given the question. I always mark answers eventually, with very few exceptions (take a look at my history). Do you think this is bad practice? – quant Oct 30 '14 at 21:46

2 Answers2

7

Wrap them in the standard NDEBUG macro.

#ifndef NDEBUG
static_assert(...);
#endif

That way for release builds you can disable them just like regular assert. Although I don't really see a purpose to this.

If you don't like wrapping up the calls in a macro, you can define a macro that does it for you:

#ifndef STATIC_ASSERT
#ifndef NDEBUG
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__)
#else
#define STATIC_ASSERT(...) static_assert(true, "")
#endif // NDEBUG
#endif // STATIC_ASSERT

Usage is similar to a regular static_assert. Note that if your program defines a keyword and includes a standard library header then it is undefined behaviour to define a static_assert macro.

Community
  • 1
  • 1
Rapptz
  • 20,807
  • 5
  • 72
  • 86
  • I'm not particularly fond of this solution, but I guess it would do the job. – quant Oct 30 '14 at 01:56
  • @quant Due to their compile-time aspect this is the only way to do it. Either that or removing them out right. – Rapptz Oct 30 '14 at 01:57
  • I really don't recommend coupling static checks (`static_assert`) with runtime-checks. If you want to remove one of them, it is quite possible you don't want to disable the others too. – Deduplicator Oct 30 '14 at 02:12
  • @Deduplicator It could be replaced by whatever macro defined during the compilation process. I just used `NDEBUG` due to familiarity. – Rapptz Oct 30 '14 at 02:13
  • 2
    The replacement `do { } while(0)` won't work for `static_assert`s in namespace scope or in class bodies. – reima Oct 30 '14 at 02:41
  • @reima Good catch. I can't think of a good way to fix that outside of moving the semicolon to the macro. Using a comment such as `/**/` will just lead a warning which is an error with -Werror. – Rapptz Oct 30 '14 at 02:44
  • How about `#define STATIC_ASSERT(...) static_assert(true, "")`? – reima Oct 30 '14 at 02:51
1
  1. You can either wrap them, each for itself, in its own #ifdef:

    #ifndef NO_STATIC_ASSERT
    static_assert(...);
    #endif
    
  2. Or, you can define your own STATIC_ASSERT:

    #ifndef NO_STATIC_ASSERT
        #define STATIC_ASSERT(...) /**/
    #else
      #define STATIC_ASSERT(...) static_assert(__VA_ARGS__)
    #endif
    
    • In practice, #define static_assert(...) works too, though it is UB.
  3. Or, you can just manually remove them.

That way you can remove their influence on compilation-performance (they never had any influence on runtime-performance anyway).

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
  • neat, I didn't think of that second one. Thanks :) – quant Oct 30 '14 at 01:59
  • 1
    defining your own `static_assert` macro is undefined behaviour – Rapptz Oct 30 '14 at 01:59
  • 3
    @Deduplicator Defining keywords through the preprocessor is undefined behaviour iif the TU or header includes a standard library header which is likely. See [here](http://stackoverflow.com/a/2726221/1381108). – Rapptz Oct 30 '14 at 02:04
  • 1
    @Deduplicator Yes. The comments by Johannes seems to support my claims and I trust him. This is a pretty old and long winded debate with a lot of history though. – Rapptz Oct 30 '14 at 02:12
  • @Deduplicator It's in the latest draft [here](https://github.com/cplusplus/draft/blob/master/source/lib-intro.tex#L2043). I don't want to prolong this discussion though. Discuss this in the [Lounge](http://chat.stackoverflow.com/rooms/10/loungec) if you want. – Rapptz Oct 30 '14 at 02:21
  • @Rapptz: No need. I looked for all the other cites, but that one is certainly enough. – Deduplicator Oct 30 '14 at 02:26