Question

J'ai une fonction qui prend une longue * et les besoins non signé pour le transmettre à une bibliothèque externe qui prend un unsigned int * et sur cette plate-forme unsigned int / long sont de la même taille.

void UpdateVar(unsigned long* var) {
   // this function will change the value at the address of var
   ExternalLibAtomicUpdateVar((unsigned int*)var); // lib atomically updates variable
}

générer un avertissement disant que son enfreindre les règles strictes-aliasing. Y a-t-il des contournements de travail?

Merci

Edit: Je suis désolé de ne pas être clair. Le code est une mise à jour atomique afin d'aller autour de la bibliothèque pour stocker ce n'est pas une option. Je pourrais descendre à l'assemblage, mais je voudrais le faire en C ++.

Était-ce utile?

La solution

void UpdateVar(unsigned long* var) {
   unsigned int x = static_cast<unsigned int>(*var);
   ExternalLibUpdateVar(&x);
   *var = static_cast<unsigned long>(x);
}

Autres conseils

Cela devrait fonctionner:

void UpdateVar(unsigned long* var) {
   // this function will change the value at the address of var
   ExternalLibUpdateVar(reinterpret_cast<unsigned int*>(var));
}

Rien dans les mandats standard C qui int et long doivent avoir la même taille; De plus, même si elles ont la même taille, rien dans les mandats standard qu'ils ont la même représentation (entre autres choses, ils pourraient avoir des combinaisons incompatibles de bits de remplissage et les représentations de piège, de sorte que l'aliasing entre les deux types ne pouvait servir tout fin utile).

Les auteurs de la norme ne voulait pas de force ciblant implémenteurs les plates-formes où l'aliasing entre int et long ne servirait à rien de reconnaître ces aliasing. Ils ne voulaient pas écrire des règles qui seraient applicables à certaines plates-formes (celles où aliasing servirait un but), mais pas d'autres (ceux où il ne serait pas). Au lieu de cela, ils ont trouvé que les gens qui écrivent des compilateurs de qualité essaieraient de reconnaître l'aliasing dans les cas où il a été utile.

Être capable d'utiliser des pointeurs à un type 32 bits à lire et les valeurs d'écriture d'un autre type 32 bits qui a la même représentation est clairement utile, surtout si les API sont divisés quant au type qu'ils attendent. Si certaines API banales sur une utilisation de la plate-forme int* pour les valeurs 32 bits et d'autres utilisent long*, qualité mise en œuvre à usage général pour cette plate-forme doit permettre aux données de chaque type à accéder à l'aide des pointeurs de l'autre.

Malheureusement, cependant, les auteurs de certains compilateurs sont plus intéressés par le traitement d'un sous-ensemble de programmes rapidement, que dans le traitement d'un sous-ensemble de programmes plus utile, et ne peuvent être invoquées pour générer du code utile s'il est nécessaire d'échanger des données entre API qui utilisent la même représentation de données, mais différents types nommés à moins d'aliasing complètement l'analyse désactive. Bien sûr, si l'on cible les dialectes de C qui conviennent à un usage général sur micro-contrôleurs, ces questions importent peu.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top