Утверждается ли GCC встроенное время компиляции?

Наша существующая реализация утверждения времени компиляции основана на отрицательном индексе массива, и он обеспечивает плохой диагностический вывод в GCC. С++ 0x static_assert - очень приятная функция, а предоставляемый ею диагностический вывод намного лучше. Я знаю, что GCC уже реализовал некоторые функции С++ 0x. Кто-нибудь знает, есть ли static_assert среди них, и если это так, то какая версия GCC?

Ответы

Ответ 2

Если вам нужна версия gcc, которая не поддерживает ее, вы можете использовать

#include <boost/static_assert.hpp>

BOOST_STATIC_ASSERT( /* assertion */ )

В основном, что такое boost:

Объявить (но не определять!) a

template< bool Condition > struct STATIC_ASSERTION_FAILURE;

Определить специализацию для случая, когда выполняется утверждение:

template <> struct STATIC_ASSERTION_FAILURE< true > {};

Затем вы можете определить STATIC_ASSERT следующим образом:

#define STATIC_ASSERT(Condition) \ 
  enum { dummy = sizeof(STATIC_ASSERTION_FAILURE< (bool)(Condition) > }

Фокус в том, что если условие false, компилятор должен создать экземпляр структуры

STATIC_ASSERTION_FAILURE< false >

чтобы вычислить его размер, и это не удается, поскольку оно не определено.

Ответ 3

Следующий код работает, как и ожидалось, с g++ 4.4.0 при компиляции с флагом -std=c++0x:

int main() {
    static_assert( false, "that was false" );
}

он отображает:

x.cpp: In function 'int main()':
x.cpp:2: error: static assertion failed: "that was false"

Ответ 4

Если у вас есть более старый gcc или используйте более старый стандарт С++ или используйте C, вы можете эмулировать static_assert, как описано здесь: http://www.pixelbeat.org/programming/gcc/static_assert.html

Ответ 5

Это на самом деле не отвечает на вопрос, но мне больше нравятся утверждения времени компиляции на основе кода коммутатора, например.

#define COMPILE_TIME_ASSERT(cond) do { switch(0) { case 0: case cond: ; } } while (0)

Работает также в C и не только на С++.

Ответ 6

вы всегда можете играть с шаблонами и несуществующими с помощью шаблона-специализации. Именно так насколько я знаю. Это то, что я использую как static_assert, это довольно прямолинейно.

namespace Internal 
{
template<bool x> struct SASSERT_F;
template<      > struct SASSERT_F <true> {};
template<int  x> struct SASSERT_P        {};
#define STATIC_ASSERT(B)            \
     typedef Internal::SASSERT_P <( \
     sizeof (Internal::SASSERT_F <( \
         ((B)? true : false))    >) \
                                 )> \
         StaticAssert##__LINE__  ()
}

Пример использования

int main(int argc, char **argv)
{
    static_assert(sizeof(int) == 1)           // Error
    static_assert(sizeof(int) == sizeof(int)) // OK
}

Ответ 7

NSPR делает:

#define PR_STATIC_ASSERT(condition) \
    extern void pr_static_assert(int arg[(condition) ? 1 : -1])

который терпит неудачу, если condition является ложным, потому что он объявляет массив отрицательной длины.

Ответ 8

И

    BOOST_STATIC_ASSERT(x)
    BOOST_STATIC_ASSERT_MSG(x, msg)

будет использовать С++ 11 static_assert, если ваш компилятор поддерживает его