Notre implémentation d'assertion de compilation à l'heure actuelle est basée sur un index de tableau négatif et fournit une mauvaise sortie de diagnostic sur GCC. Le static_assert
de C++ 0x est une fonctionnalité très intéressante, et la sortie de diagnostic qu'elle fournit est bien meilleure. Je sais que GCC a déjà implémenté des fonctionnalités C++ 0x. Est-ce que quelqu'un sait si static_assert
est parmi eux et si c'est alors depuis quelle version de GCC?Est-ce que GCC a un temps de compilation intégré?
Répondre
Le code suivant fonctionne comme prévu avec g ++ 4.4.0 lorsqu'il est compilé avec le drapeau -std=c++0x
:
int main() {
static_assert(false, "that was false");
}
affiche:
x.cpp: In function 'int main()':
x.cpp:2: error: static assertion failed: "that was false"
Si vous avez besoin d'utiliser une version gcc qui ne le soutenir, vous pouvez utiliser
#include <boost/static_assert.hpp>
BOOST_STATIC_ASSERT(/* assertion */)
Fondamentalement, ce que le coup de pouce est le suivant:
Declare (mais ne définit pas!) Un
template< bool Condition > struct STATIC_ASSERTION_FAILURE;
Définir une spécialisation dans le cas où l'affirmation est vérifiée:
template <> struct STATIC_ASSERTION_FAILURE<true> {};
Ensuite, vous pouvez définir static_assert comme ceci:
#define STATIC_ASSERT(Condition) \
enum { dummy = sizeof(STATIC_ASSERTION_FAILURE< (bool)(Condition) > }
L'astuce est que si Condition est faux le compilateur doit instancier la structure
STATIC_ASSERTION_FAILURE<false>
afin de calculer sa taille, et cela échoue car il n'est pas défini.
Je me demande s'il y a un moyen de faire apparaître un message d'erreur sensible à partir d'un truc comme celui-ci ... – Thomas
Selon la documentation (http://www.boost.org/doc/libs/1_43_0/doc/html/boost_staticassert. html), c'est l'un des objectifs de Boost.StaticAssert: "L'un des objectifs de BOOST_STATIC_ASSERT est de générer des messages d'erreur lisibles. Cela indique immédiatement à l'utilisateur qu'une bibliothèque est utilisée d'une manière qui n'est pas supportée. " – Philipp
Il y a une parenthèse manquante dans' ... (Condition)>} ', devrait probablement être' ... (Condition)>)} '. J'ai essayé d'éditer ceci mais a été rejeté ... – mbschenkel
Cela ne répond pas vraiment à la question, mais j'aime les affirmations à la compilation basées sur le cas de commutation mieux, par exemple.
#define COMPILE_TIME_ASSERT(cond) do { switch(0) { case 0: case cond: ; } } while (0)
Fonctionne également en C et pas seulement en C++.
Cette technique a deux défauts. Premièrement, une telle assertion ne peut pas être utilisée au niveau de la classe ou de l'espace de noms. Et deuxièmement, lorsque l'assertion est réussie, elle génère du code exécutable, ce qui gonfle le binaire. Il revient à votre compilateur optimiseur de l'enlever, ce qui n'est pas garanti. :-( – VladLosev
Si vous avez un gcc plus âgé ou utilisez un ancien standard C++, ou utilisez C, vous pouvez émuler static_assert comme décrit ici: http://www.pixelbeat.org/programming/gcc/static_assert.html
vous pouvez toujours jouer avec des modèles et des non-Existant strutures par modèle -spécialisation. C'est ainsi que boost le fait autant que je sache. C'est ce que j'utilise comme static_assert, c'est assez simple.
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__ ()
}
Exemple d'utilisation
int main(int argc, char **argv)
{
static_assert(sizeof(int) == 1) // Error
static_assert(sizeof(int) == sizeof(int)) // OK
}
NSPR fait:
#define PR_STATIC_ASSERT(condition) \
extern void pr_static_assert(int arg[(condition) ? 1 : -1])
qui échoue si condition
est faux car il déclare un tableau de longueur négative.
deux
BOOST_STATIC_ASSERT(x)
BOOST_STATIC_ASSERT_MSG(x, msg)
utilisera le 11 C++ static_assert si votre compilateur supporte
- 1. gcc compilation des notes de temps/msg
- 2. Problème compilation gcc 4.4.0 sur OpenSolaris 2009.6
- 3. compilation 64 noyau linux bits avec gcc
- 4. Compilation avec gcc (cygwin sur windows)
- 5. Est-ce que jQuery a intégré le support JSON?
- 6. Est-ce que quelqu'un a intégré NCover avec TFS?
- 7. Temps de compilation dans .Net 3.5
- 8. temps de liaison de profil avec gcc/g ++ et ld
- 9. Est-ce que AssemblyCleanup a une limite de temps
- 10. Erreur d'assemblage en ligne, contrecarrant les tentatives de compilation gcc
- 11. Erreur lors de la compilation C++ fichier Dans GCC
- 12. Est-ce que l'iphone a un dictionnaire intégré auquel d'autres applications peuvent accéder?
- 13. Est-ce que Silverlight a un VirtualizingStackPanel?
- 14. Est-ce que quelqu'un a utilisé Open Office intégré dans une application de bureau .NET?
- 15. Utilisation de gcc avec ccache
- 16. Est-ce que java.lang.Math.PI est égal à M_PI de GCC?
- 17. Y a-t-il un attribut de paire nom/valeur intégré?
- 18. solutions de compilation/compilation multi-plateforme
- 19. que signifie "POR" dans le développement intégré?
- 20. Comment vérifier si gcc a échoué, a renvoyé un avertissement ou réussi? (dans bash)
- 21. Erreur de compilation
- 22. Est-ce que Firebug a quelque chose de intégré pour désactiver tous les javascript pour un site/une page?
- 23. PHP preg_replace() compilation a échoué: manquant)
- 24. Comment tester au moment de la compilation la version actuelle de GCC?
- 25. Y a-t-il un moyen intégré d'afficher/cacher un élément dans jQuery?
- 26. Comment puis-je utiliser html/javascript pour que le lien <a> déclenche un objet flash intégré?
- 27. TestFixtureSetUp a échoué de temps en temps lors de l'exécution de cc.net
- 28. Y a-t-il un truc pour gagner du temps dans Xcode quand il y a des milliers d'images?
- 29. Est-ce que Ruby a un built-in do ... while?
- 30. A « _ » chaque fois que j'utiliser un <a href Code
http://en.wikichip.org/wiki/c/static_assertions –