Nuestra implementación de afirmación en tiempo de compilación existente se basa en un índice de matriz negativo y proporciona una salida de diagnóstico deficiente en GCC. C++ 0x static_assert
es una característica muy agradable, y la salida de diagnóstico que proporciona es mucho mejor. Sé que GCC ya ha implementado algunas características de C++ 0x. ¿Alguien sabe si static_assert
está entre ellos y si es así desde qué versión de GCC?¿GCC tiene un tiempo de compilación incorporado?
Respuesta
El siguiente código funciona como se esperaba con g ++ 4.4.0 cuando se compila con la bandera -std=c++0x
:
int main() {
static_assert(false, "that was false");
}
muestra:
x.cpp: In function 'int main()':
x.cpp:2: error: static assertion failed: "that was false"
Si es necesario utilizar una versión de gcc que no lo hace apoyarlo se puede usar
#include <boost/static_assert.hpp>
BOOST_STATIC_ASSERT(/* assertion */)
Básicamente, lo que aumenta es esto:
declare (pero no definen!) Un
template< bool Condition > struct STATIC_ASSERTION_FAILURE;
definir una especialización para el caso de que la afirmación sostiene:
template <> struct STATIC_ASSERTION_FAILURE<true> {};
Entonces se puede definir static_assert así:
#define STATIC_ASSERT(Condition) \
enum { dummy = sizeof(STATIC_ASSERTION_FAILURE< (bool)(Condition) > }
El truco es que si la condición es falsa, el compilador necesita crear una instancia de la estructura
STATIC_ASSERTION_FAILURE<false>
para calcular su tamaño, y esto falla porque no está definido.
Me pregunto si hay alguna manera de hacer que aparezca un mensaje de error sensible de un truco como este ... – Thomas
Según la documentación (http://www.boost.org/doc/libs/1_43_0/doc/html/boost_staticassert. html), este es uno de los objetivos de Boost.StaticAssert: "Uno de los objetivos de BOOST_STATIC_ASSERT es generar mensajes de error legibles. Estos inmediatamente le dicen al usuario que una biblioteca está siendo utilizada de una manera que no es compatible. " – Philipp
Falta un paréntesis en' ... (Condición)>} ', probablemente debería ser' ... (Condición)>)} '. Traté de editar esto, pero fue rechazado ... – mbschenkel
Esto realmente no responde la pregunta, pero me gustan más las aseveraciones en tiempo de compilación basadas en el conmutador, p. Ej.
#define COMPILE_TIME_ASSERT(cond) do { switch(0) { case 0: case cond: ; } } while (0)
Funciona también en C y no solo en C++.
Esta técnica tiene dos deficiencias. En primer lugar, dicha afirmación no se puede utilizar a nivel de clase o espacio de nombres. Y segundo, cuando la aserción tiene éxito, genera código ejecutable, inflando el binario. Le queda a su compilador de optimización para eliminarlo, y eso no está garantizado. :-( – VladLosev
Si usted tiene un gcc de esa edad o utiliza un estándar antiguo C++, o utilizar C, entonces se puede emular static_assert como se describe aquí: http://www.pixelbeat.org/programming/gcc/static_assert.html
siempre se puede jugar con las plantillas y al loro strutures a través de la plantilla -especialización. Así es como lo hace el impulso hasta donde yo sé. Esto es lo que uso como static_assert, es bastante directo.
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__ ()
}
Ejemplo de uso
int main(int argc, char **argv)
{
static_assert(sizeof(int) == 1) // Error
static_assert(sizeof(int) == sizeof(int)) // OK
}
NSPR hace:
#define PR_STATIC_ASSERT(condition) \
extern void pr_static_assert(int arg[(condition) ? 1 : -1])
que falla si condition
es falso porque declara una matriz de longitud negativa.
Tanto
BOOST_STATIC_ASSERT(x)
BOOST_STATIC_ASSERT_MSG(x, msg)
utilizará el static_assert C++ 11 si su compilador soporta
- 1. GCC optimización en tiempo flotante en tiempo de compilación
- 2. ¿Cómo se calcula el tiempo de compilación de gcc?
- 3. ¿Rails tiene un sistema de autenticación incorporado?
- 4. ¿Tiene MFC incorporado un control de cuadrícula?
- 5. ¿Android tiene un visor de PDF incorporado?
- 6. ¿Ruby tiene un método string.startswith ("abc") incorporado?
- 7. lento tiempo de compilación con GCC Boost + + encabezado precompilado
- 8. Tiempo de compilación typeid sin RTTI con GCC
- 9. Compilación de un programa C++ con gcc
- 10. ¿Por qué Ruby no tiene un ThreadPool incorporado?
- 11. ¿Por qué Dart tiene constantes de tiempo de compilación?
- 12. GCC-4.7 Compilación
- 13. ¿GCC tiene una GUI?
- 14. ¿.NET tiene incorporado EventArgs <T>?
- 15. Preguntas generales sobre GCC y compilación cruzada
- 16. ¿Cómo demuestro el valor de un # define en tiempo de compilación en GCC
- 17. ¿Por qué Python no tiene un getattr híbrido + __getitem__ incorporado?
- 18. ¿.NET 4 tiene un serializador/deserializador JSON incorporado?
- 19. Comparación de tiempo de compilación entre el compilador de Windows GCC y MSVC
- 20. error de compilación de gcc de python
- 21. Cygwin GCC Cross binarios de compilación?
- 22. Obtener tiempo de compilación JAR
- 23. Valores enteros en tiempo de compilación
- 24. ¿Cómo pruebo en tiempo de compilación la versión actual de GCC?
- 25. ¿Tiene tiempo de "holgura"?
- 26. Tiempo de compilación de perfiles
- 27. la compilación de archivos de objetos no esencial con GCC
- 28. offsetof en tiempo de compilación
- 29. GCC#pragma para detener la compilación
- 30. Compilación con gcc (cygwin en windows)
http://en.wikichip.org/wiki/c/static_assertions –