0
votes

AVERTISSEMENT: Cast de 'Char *' à 'Float *' augmente l'alignement requis de 1 à 4 [-Wast-align]


3 commentaires

Quelque chose me dit que l'avertissement peut être supprimé par la coulée sur Void * en premier.


Pourquoi ne pas utiliser static_cast sur un flotteur *? Est-ce que cela supprimer l'avertissement?


Comment obtient-il () sache combien de caractères il devrait mettre dans son mémoire tampon?


3 Réponses :


1
votes

sous quel genre de conditions? S'il renvoie toujours un tampon de flotteur, faites-le donc ( float * obtenez () ), si parfois ce n'est pas le cas, un décorateur statique ne vous aidera pas.

Si vous savez que le pointeur retourné pointe vers un flotteur, réinterpret_cast peut être utilisé. Si ce n'est pas le cas, mais vous voulez toujours un flotteur, MEMCY ou Bit_Cast (C ++ 20) peut être utilisé.


0 commentaires

3
votes

Je recommanderais de l'utilisation de couts de style C et de favoriser REINTERPRET_CAST CODE>. Cela a également la belle propriété de se débarrasser de l'avertissement.

Cependant, pour répondre à votre question appropriée: p>

Depuis C ++ 20, vous pouvez utiliser std :: assume_aligné code> comme: p>

extern char* get();

void foo()
{
  float *f = (float*)__builtin_assume_aligned(get(), alignof(float));
}


11 commentaires

et probablement std :: alignment_of_v au lieu de 4 .


toujours je honte que je ne puisse pas décorer la fonction réelle à la place.


La question demande c ++ 11 cependant. Pas de vote de moi cependant, car il est toujours pratique de connaître d'autres versions de C ++.


Si le pointeur est renvoyé par get () n'est pas aligné, std :: assume_aligné ne vous aidera pas si je comprends le wiki correctement. " Le comportement est indéfini si PTR ne pointe pas sur un objet de type T (ignorant la qualification CV à tous les niveaux), "


@Chipster d'où le commentaire "Pré-C ++ 20" ci-dessous.


@Tedlyngmo Cette hypothèse est explicitement reconnue par OP. Sous certaines conditions, je sais que le tampon retourné par Get () contiendra un tampon à virgule flottante correctement aligné.


Oui, ok, mais qu'est-ce que std :: assume_aligned aide vraiment si vous le direz d'assumer float alignement pour quelque chose qui a float alignement? Quelle optimisation pourrait éventuellement être faite avec cette information? Il semble ne être utile que lors de la fourniture d'un alignement plus grand que ce que le type d'origine nécessite. Pas certain ...


@Tedlyngmo Il a un alignement flottant, mais le compilateur ne sait pas que . C'est essentiellement une assistante d'analyse statique.


"car c ++ 20" sonne comme nous sommes dans> = 2020 :)


@MilleniumBug ne devrait pas le compilateur à faire la même hypothèse lorsque vous Reterpret_cast ? Il serait étrange si cela ne l'avait pas accédé à la mémoire indiquée via le float * serait également UB s'il n'était pas aligné.


... et ne devrait-il pas être: float * f = std :: assume_aligné (réinterpret_cast (get ()));



1
votes

Les avertissements ne sont que des messages du compilateur pour avertir le programmeur (vous) que quelque chose est suspect. Dans le cas général, convertir à partir d'un Char * à un float * peut provoquer des problèmes d'alignement d'où l'avertissement.

Si vous savez que dans votre cas d'utilisation, aucun problème d'alignement ne se produira jamais et qu'un aliasing strict n'est pas un problème non plus, vous pouvez ignorer en toute sécurité l'avertissement. Assurez-vous de laisser un commentaire dans le code des futurs mainteneurs de ne pas vous inquiéter de cet avertissement à cet endroit.

Après avoir lu à nouveau la dernière ligne de votre question, je ne voudrais pas utiliser le tampon de données d'un vecteur pour cette utilisation. Au moins, vous devriez utiliser un vecteur : par définition, il peut contenir des flotteurs et il est toujours sûr d'accéder à n'importe quel type (une matrice ou des flotteurs) en tant que tableau de caractères.


9 commentaires

Il s'avère que c'est en fait la meilleure réponse, pas idéal puisque je voudrais avoir un mot-clé pour la fonction réelle. Mais changer la signature de fonction pour revenir void * veillera à ce que l'utilisateur lira réellement la documentation.


Le problème est que je ne vois aucune preuve dans la question que l'avertissement est de quelque manière que ce soit. Pourquoi tout le monde recommande-t-il de l'inhiber?


@LightnessRacsinorbit: OP a dit en question: Sous certaines conditions, je sais que le tampon retourné par Get () contiendra une tampon à virgule flottante correctement alignée . Comme cela ferait un compilateur aimable, j'invie-moi qu'il est responsable de l'alignement et du strict considérant le respect de l'aliasing, et je lui fais confiance de savoir ce qu'il fait. i sais, que si obtenez renvoie un tampon malloc ou un pointeur sur un flotteur ou un tableau de flotteur, alors ce sera amende.


@Sergeballesta Ils ont également dit qu'il provient d'un std :: vecteur . Ça va bien?


@LightnessRacsinorbit: Proche d'un débat sexuel Angels :-). C'est certainement UB, mais j'avais lu des implémentations vectorielles et toutes les personnes utilisent un tampon alloué pour leurs données. Si profondément dans les internes de la bibliothèque standard, le tampon de données de vecteur n'a aucun type déclaré et est correctement aligné pour tout type. Mais je dois admettre que je n'utiliserais pas cela dans le code de production!


@Sergeballesta ok non Ça a du sens réellement


@LightnessRacsinorbit: Quoi qu'il en soit, j'ai modifié mon poste pour mieux refléter la question que vous avez soulevée.


@Sergeballesta merci pour la modification. J'étais sous l'impression que la norme C ++ nécessite des fonctions d'allocation (MALLOC () et NOUVEAU Opérateur ()) d'allouer de la mémoire convenablement alignée sur n'importe quel type standard (par exemple, float ou double ). Depuis que STD interne :: Les données vectorielles sont allouées, je ne comprends pas votre dernier commentaire (édité).


@Malat: Le problème est que comme indiqué par LightnessRacesinorbit, vous pouvez toujours stocker une représentation de flotteur dans l'élément de données d'un vecteur , mais en utilisant le type punning pour l'utiliser comme un flotteur est formellement ub. , même si la plupart des implémentations ne le permettront pas. L'allocator est censé renvoyer un tableau de charcuterie lorsque vous demandez, mais je ne pense pas qu'il garantit que le tableau de caractères n'a aucun type déclaré.