2010-05-05 5 views
18

Pour autant que je comprends, GCC prend en charge toutes ses fonctions de C99 en C++. Mais comment gérer l'alias strict C99 dans le code C++?C99 règles strictes d'aliasing en C++ (GCC)

Je sais que la coulée avec C moulages entre les types non apparentés est sans aliasing de sécurité stricte et peut générer un code incorrect, mais qu'en est-C++? Puisque l'aliasing strict ne fait pas partie de la norme C++ (est-ce correct?), GCC doit spécifier la sémantique elle-même.

Je figure const_cast et static_cast cast entre les types liés, d'où ils sont sûrs, tandis que reinterpret_cast peut briser les règles strictes d'aliasing.

Est-ce une compréhension correcte?

Répondre

31

Non, vous mélangez probablement des choses différentes.

règles strictes ont crénelage absolument rien à voir spécifiquement avec la norme C99. Les règles d'alias strictes sont enracinées dans les parties de la norme qui étaient présentes en C et C++ depuis le début des temps [standardisés]. La disposition qui interdit l'accès aux objets d'un type à travers un lvalue d'un autre type est présent en C89/90 (6,3) et en C++ 98 (3,10/15). C'est ce que le strict aliasing signifie, pas plus, pas moins. C'est juste que tous les compilateurs n'ont pas voulu (ou osé) l'imposer ou s'en servir. Les langages C et C++ sont parfois utilisés comme langages d'assemblage de haut niveau et les règles strictes d'alias interfèrent souvent avec ces utilisations. C'est GCC qui a fait ce choix audacieux et a décidé de commencer à s'appuyer sur des règles strictes d'aliasing dans les optimisations, en tirant souvent des plaintes de ces types "d'assemblage".

Il est vrai que la manière la plus directe de casser les règles strictes d'aliasing en C++ est reinterpret_cast (et la distribution de style C, bien sûr). Cependant, static_cast peut également être utilisé à cette fin, car elle permet de casser aliasing strict en utilisant void * comme un type intermédiaire dans une « chaîne » cast

int *pi; 
... 
double *pd = static_cast<double *>(static_cast<void *>(pi)); 

const_cast ne peut pas briser aliasing strict dans un compilateur conforme.

Quant au C99 ... Ce C99 a fait place était le qualificatif restrict. Ceci est directement lié à l'aliasing, mais ce n'est pas ce que l'on appelle le strict aliasing en soi.

+1

Vous avez raison, je pensais C99 mot-clé 'restrict', plutôt que strict aliasing. Pour une raison ou une autre, il s'est ancré dans mon esprit de cette façon ("C99" + "strict aliasing"). –

+0

Alors, quelle est exactement la clause en question?Cela signifie-t-il que tout code C89/C99/C++ 98 qui enfreint les règles strictes d'aliasing est techniquement incorrect (à l'exception des commutateurs spécifiques au compilateur comme -fno-strict-aliasing)? –

+0

@Checkers: J'ai ajouté les chiffres à ma réponse. Et oui, le code qui brise les règles strictes d'alias présente un comportement indéfini, aussi bien en C89 qu'en C++ 98. – AnT

4

static_cast peut également rompre les règles d'alias, car le compilateur vous fait confiance pour vous assurer que le type cible est lié au type d'exécution réel de l'objet. Considérons:

extern void f(double*, int*); // compiler may optimize assuming that arguments don't overlap 
double d; 
void* pv = &d; 
int* pi = static_cast<int*>(pv); 
f(&d, pi); // assumption is violated 
2

Le concept est le même dans Cpp; en ce que vous pouvez utiliser des moulages de style C pour vous guider à travers ce qui est considéré comme sûr par un aliasing strict. En bref: non, l'approche de l'utilisation de Cast Cpp (que vous avez esquissée) ne couvrira pas tous les cas en toute sécurité. Une façon courante de casser les règles est d'utiliser static_cast pour lancer des pointeurs.

Il suffit d'afficher les avertissements du compilateur - il (ou, devrait) vous dire ce qui est dangereux.

Questions connexes