J'ai une application qui lit actuellement les données d'un flux (socket, named, pipe, stdin, peu importe) dans un tampon char
puis utilise reinterpret_cast
pour pointer un Foo *
(où Foo
est un POD) dans le milieu du tampon et puis travaille avec le contenu du tampon à travers ce pointeur. Maintenant, ceci brise des règles strictes d'aliasing, bien que je doute que cela causerait réellement un problème dans la pratique. Pourtant, existe-t-il une façon acceptée de le faire en Standard C++? Parce que nous sommes potentiellement en train de transférer des centaines de gigaoctets de cette façon, et ne voulons en aucun cas introduire le surcoût de la copie de ces données hors du tampon dans une structure avec memcpy
.Existe-t-il un moyen conforme aux normes de faire du protocole IPC sans copie en C++?
Pour être clair, le code ressemble à ceci:
MessageData *msg = new MessageData();
while (ipc.we_have_data()) {
ipc.read(msg);
char *buf = msg->data();
Header *h = reinterpret_cast<Header *>(buf);
if (h->tag == 0) {
Payload *p = reinterpret_cast<Payload *>(buf + sizeof(Header));
do_stuff_with_payload(p);
} else if (h->tag == 1) {
// etc...
}
}
Je me rends compte qu'il peut y avoir des problèmes d'alignement, mais ils ne me regardent pas à ce point. Les données sont produites sur la même plate-forme par le même compilateur, donc il n'y a pas de problèmes avec la disposition des membres de la structure étant différente. Mais, si je comprends bien, cela brise techniquement les règles strictes d'aliasing.
Existe-t-il un moyen efficace de le faire qui ne brise pas les règles strictes d'alias?
Ou est-ce que je me trompe complètement, et c'est très bien par ces règles?
Si oui, pourquoi?
Modifier: Un commentaire supprimé pointait vers ce definition of the aliasing rules qui indique que char *
obtient un laissez-passer gratuit. Donc, mon exemple ne brise pas les règles strictes d'aliasing. Quelqu'un connaît-il la bonne section de la norme pour cela?
Les problèmes d'alignement peuvent souvent être traités efficacement. Traiter le crénelage nécessite soit d'utiliser un compilateur qui peut être utilisé pour reconnaître certaines constructions d'aliasing évidentes, écrire du code lent et inefficace et espérer que le compilateur peut le transformer en un code sensible que l'on voulait écrire en premier, ou en écrivant les compilateurs n'espéreront pas comment casser. Je ne sais pas pourquoi certains rédacteurs de compilateurs semblent être farouchement opposés à # 1, car la reconnaissance de certaines constructions évidentes semblerait plus facile que d'essayer de faire du code efficace à partir d'un désordre conforme aux normes. – supercat
@supercat - Je ne sais pas pourquoi. Cela semble être quelque chose qui devrait vraiment être ajouté à la norme C++, une façon approuvée de faire certains types d'alias. La capacité de faire des choses comme ça fait partie de la raison pour laquelle les gens utilisent des langages comme C et C++ en premier lieu. – Omnifarious
@Omnifarious: Ce qui rend la situation très triste, c'est que si la norme avait simplement donné aux implémentations la permission de faire des suppositions d'alias quand cela aurait un sens *, et a traité le fait que certaines implémentations pourraient ne pas reconnaître certains types d'aliasing comme étant quelque peu analogue au fait que certaines implémentations peuvent mourir si les programmes imbriquent certains appels de fonctions 30 profonds (ou, d'ailleurs, 3 profonds), mais suggèrent que les implémentations de qualité devraient gérer tous les types d'aliasing sensés étant donné la plate-forme cible et l'application field ... – supercat