2017-06-29 3 views
2

Sur this page concernant une certaine structure Winsock, l'exemple semble prendre l'adresse d'une structure et convertir le pointeur en un pointeur vers une structure complètement différente.Aliasing strict C++: cet exemple MSFT n'est-il pas UB?

SOCKET ListenSocket; 
struct sockaddr_in saServer; 
// Bind the listening socket using the information in the sockaddr structure 
bind(ListenSocket,(SOCKADDR*) &saServer, sizeof(saServer)); 

Voici les déclarations pour les deux structures. C'est un comportement techniquement indéfini, correct?

struct sockaddr { 
     ushort sa_family; 
     char sa_data[14]; 
}; 

struct sockaddr_in { 
     short sin_family; 
     u_short sin_port; 
     struct in_addr sin_addr; 
     char sin_zero[8]; 
}; 
+0

Les jetons de pointeur ne transgressent jamais la stricte règle d'aliasing (il semble que ce soit une idée fausse commune) –

+1

@MM, mais sûrement l'implémentation de 'bind' va devoir déférencer ce pointeur, et au point * que vous violez la règle stricte d'aliasing, non? (J'ai la vague impression que vous pouvez être sauvé par le fait que le seul élément de la structure étant lu par l'alias est au début de la structure et est commun aux deux, mais il n'est pas du tout évident pour moi que cela est vrai du point de vue langue avocat) –

+0

implémentations bibliothèque @HarryJohnston ne sont pas soumis à des règles ISO C++, ils pourraient même ne pas être écrites en C++ –

Répondre

2

Entre l'aube de C (qui remonte au moins à 1974) et 1989, si deux structures partagées une séquence initiale commune, la langue du code a permis sans ambiguïté d'utiliser un pointeur d'un type de structure pour inspecter les membres de la CEI de L'autre. Dans la norme C99, cette autorisation était limitée aux cas où les deux types de structure faisaient partie d'un type d'union dont la déclaration complète était visible au point où la valeur CIS est inspectée; Certaines personnes insistent sur le fait que parce que les auteurs de 1989 voulaient imposer une telle restriction, cela s'applique également à C89. En outre, certains rédacteurs de compilateurs insistent sur le fait que les auteurs de la norme ont seulement voulu que cette garantie s'applique aux accès faits à travers des lvalues ​​de type union, ils ignoreront la partie de la norme qui dit qu'une définition de «union complète tapez "doit être visible.

Les implémentations sont autorisées à fournir des garanties autres que celles requises par la norme. Parce que les personnes non psychiques qui écrivent du code avant C99 n'avaient aucune raison de penser qu'elles auraient besoin d'inclure des déclarations syndicales inutiles pour exploiter les garanties de SIC, et parce que beaucoup de code écrit à partir de cette époque repose sur ces garanties malgré une manque de telles déclarations, toute personne voulant écrire une mise en œuvre approprié pour une utilisation avec un tel code doit les prendre en charge si la norme nécessite ou non un tel support. Bien qu'il n'y ait pas de raison particulière pour laquelle les mises à jour du fichier d'en-tête ne doivent pas inclure une déclaration de type union, je ne suis pas sûr du nombre de compilateurs qui se soucieraient de sa présence ou de son absence. Les compilateurs que j'ai vus supportent les garanties de CIS même sans une déclaration complète de type d'union visible, ou déshonorent les garanties de CIS (ignorant la norme) même quand la déclaration est présente.