2009-06-12 6 views
16

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é?

+1

http://en.wikichip.org/wiki/c/static_assertions –

Répondre

29

Selon this page, gcc a eu static_assert depuis 4.3.

+19

+1 pour ne pas utiliser LMGTFY . – Johnsyweb

8

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" 
16

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.

+2

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

+0

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

+0

Il y a une parenthèse manquante dans' ... (Condition)>} ', devrait probablement être' ... (Condition)>)} '. J'ai essayé d'éditer ceci mais a été rejeté ... – mbschenkel

1

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++.

+4

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

1

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 
} 
1

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.

0

deux

BOOST_STATIC_ASSERT(x) 
    BOOST_STATIC_ASSERT_MSG(x, msg) 

utilisera le 11 C++ static_assert si votre compilateur supporte

Questions connexes