Static assert for constant variables?

Static statements are very convenient for checking things at compile time. A simple static idiom of a statement looks like this:

template<bool> struct StaticAssert;
template<> struct StaticAssert<true> {};

#define STATIC_ASSERT(condition) do { StaticAssert<(condition)>(); } while(0)

This is useful for things like

STATIC_ASSERT(sizeof(float) == 4)

and

#define THIS_LIMIT (1000)
...
STATIC_ASSERT(THIS_LIMIT > OTHER_LIMIT);

But use is #definenot a "C ++" way of defining constants. C ++ will use an anonymous namespace:

namespace {
    const int THIS_LIMIT = 1000;
}

or even:

static const int THIS_LIMIT = 1000;

The problem is that with const intyou cannot use STATIC_ASSERT(), and you must resort to checking the runtime, which is stupid.

Is there a way to solve this correctly in current C ++?
I think I read C ++ 0x has some features for this ...


EDIT

So this is

static const int THIS_LIMIT = 1000;
...
STATIC_ASSERT(THIS_LIMIT > 0);

compiles fine
But this:

static const float THIS_LIMIT = 1000.0f;
...
STATIC_ASSERT(THIS_LIMIT > 0.0f);

no.
(in Visual Studio 2008)

How did it happen?

+5
6

const int:

#define static_assert(e) extern char (*ct_assert(void)) [sizeof(char[1 - 2*!(e)])]
static_assert( THIS_LIMIT > OTHER_LIMIT )

, boost!

BOOST_STATIC_ASSERT( THIS_LIMIT > OTHER_LIMIT )

... ...

+10

static_assert - ++ 0x, , . , #define static_assert(x) ..., ++ 0x, . , ++ 0x static_assert (, static_assert(sizeof(int) == 4, "Expecting int to be 4 bytes")), , #define.

+4

, , ( GCC 4.3.4, Visual ++ 2008 Express):

template<bool> struct StaticAssert;
template<> struct StaticAssert<true> {};

#define STATIC_ASSERT(condition) do { StaticAssert<(condition)>(); } while(0)


static const int   AN_INT  = 1000;
static const float A_FLOAT = 1000.0f;

int main()
{
   STATIC_ASSERT(AN_INT > 0);     // OK
   STATIC_ASSERT(A_FLOAT > 0.0f); // Error: A_FLOAT may not appear in a constant expression
}

. , , . , :

[C++11: 5.19/2]: , (3.2), (5.14), ( 5.15), (5.16) , , [: . -end note] :

  • [..]
  • lvalue-to-rvalue (4.1),
    • , const ,
    • glvalue literal, , constexpr, - ,
    • glvalue literal, , , ;
  • [..]

(.. , .)

, , - :

[C++11: 5.19/4]: [..] , , , ( ) . [..]

+2

You might be confusing C ++ behavior with C, where it const intdoes not represent the true compile-time constant. Or maybe your C ++ compiler is corrupted. If this is really the last, use enuminstead.

+1
source

It:

namespace {
    const int THIS_LIMIT = 1000;
}

template<bool> struct StaticAssert;
template<> struct StaticAssert<true> {};

#define STATIC_ASSERT(condition) do { StaticAssert<(condition)>(); } while(0)

int main()
{
    STATIC_ASSERT(THIS_LIMIT > 5);

    return (0);
}

compiles great with VC and Comeau.

+1
source

enum{THIS_LIMIT = 1000};

0
source

All Articles