42 votes

La barre oblique inversée est-elle acceptable dans les directives #include de C et C++ ?

Il existe deux séparateurs de chemin d'accès couramment utilisés : le forward-slash d'Unix et le backslash de DOS. <sup>Repose en paix, Mac colon classique. </sup> S'ils sont utilisés dans une directive #include, sont-ils égaux selon les règles des normes C++11, C++03 et C99 ?

50voto

Potatoswatter Points 70305

C99 dit (§6.4.7/3) :

Si les caractères ', \, ", // ou /* apparaissent dans la séquence entre les délimiteurs < et >, le comportement est indéfini. De même, si les caractères ', \, // ou /* apparaissent dans la séquence entre les délimiteurs ", le comportement est indéfini.

(note de bas de page : Ainsi, les séquences de caractères qui ressemblent à des séquences d'échappement provoquent un comportement non défini).

C++03 dit (§2.8/2) :

Si l'un des caractères ' ou \, ou l'une des séquences de caractères /* ou // apparaît dans une séquence q-char ou une séquence h-char, ou si le caractère " apparaît dans une séquence h-char, le comportement est indéfini.

(note de bas de page : Ainsi, les séquences de caractères qui ressemblent à des séquences d'échappement provoquent un comportement non défini).

C++11 dit (§2.9/2) :

L'apparition de l'un ou l'autre des caractères ' ou \ ou de l'une ou l'autre des séquences de caractères /* ou // dans une séquence de q-chars ou une séquence de h-chars est prise en charge de manière conditionnelle avec une sémantique définie par l'implémentation, tout comme l'apparition du caractère " dans une séquence de h-chars.

(note de bas de page : Ainsi, une séquence de caractères qui ressemble à une séquence d'échappement peut entraîner une erreur, être interprétée comme le caractère correspondant à la séquence d'échappement, ou avoir une signification complètement différente, selon l'implémentation).

Par conséquent, bien que n'importe quel compilateur puisse choisir de prendre en charge une barre oblique inversée dans un fichier #include Il est peu probable qu'un compilateur ne prenne pas en charge le slash avant, et les backslashes sont susceptibles de faire échouer certaines implémentations en raison de la formation de codes d'échappement. (Edition : apparemment MSVC exigeait auparavant des backslashs. Peut-être que d'autres sur les plateformes dérivées du DOS étaient similaires. Hmmm que puis-je dire).

C++11 semble pour assouplir les règles, mais "supporté sous conditions" n'est pas vraiment mieux que "provoque un comportement non défini". Ce changement vise davantage à refléter l'existence de certains compilateurs populaires qu'à décrire une norme portable.

Bien sûr, rien dans ces normes ne dit que les chemins existent. Il y a sont systèmes de fichiers sans chemin d'accès ! Cependant, de nombreuses bibliothèques supposent des noms de chemin, y compris POSIX et Boost, il est donc raisonnable de vouloir un moyen portable de se référer aux fichiers dans les sous-répertoires.

7voto

trojanfoe Points 61927

Le slash avant est la bonne méthode ; le précompilateur fera ce qu'il faut sur chaque plateforme pour atteindre le bon fichier.

7voto

abarnert Points 94246

Cela dépend de ce que vous entendez par "acceptable".

Il existe deux sens dans lesquels les barres obliques sont acceptables et les barres obliques inversées ne le sont pas.

Si vous écrivez en C99, C++03 ou C1x, les barres obliques inversées ne sont pas définies, alors que les barres obliques sont légales, donc dans ce sens, les barres obliques inversées ne sont pas acceptables.

Mais cela n'est pas pertinent pour la plupart des gens. Si vous écrivez C++1x, où les antislashes sont supportés de manière conditionnelle, et que la plate-forme pour laquelle vous codez les supporte, ils sont acceptables. Et si vous écrivez un "dialecte étendu" de C99/C++03/C1x qui définit les backslashes, même chose. Et, plus important encore, cette notion d'"acceptable" est plutôt dénuée de sens dans la plupart des cas de toute façon. Aucun des standards C/C++ ne définit ce que signifient les slashs (ou ce que signifient les backslashes lorsqu'ils sont supportés de manière conditionnelle). Les noms d'en-têtes sont mappés aux fichiers sources d'une manière définie par l'implémentation, point final. Si vous avez une hiérarchie de fichiers, et que vous vous demandez s'il faut utiliser des barres obliques inverses ou des barres obliques pour les référencer de manière portable dans les directives #include, la réponse est : aucun des deux n'est portable. Si vous voulez écrire du code vraiment portable, vous ne pouvez pas utiliser des hiérarchies de fichiers d'en-tête - en fait, on peut dire que votre meilleur pari est de tout écrire dans un seul fichier source, et de ne rien inclure sauf les en-têtes standard.

Cependant, dans le monde réel, les gens veulent souvent "suffisamment portable", et non "strictement portable". La norme POSIX définit ce que signifient les slashs, et même au-delà de POSIX, la plupart des plates-formes modernes - y compris Win32 (et Win64), les compilateurs croisés pour les plates-formes embarquées et mobiles telles que Symbian, etc. Toute plate-forme qui ne le fait pas, n'aura probablement aucun moyen pour vous d'obtenir votre arbre source sur elle, de traiter votre makefile/etc., et ainsi de suite, donc les directives #include seront le dernier de vos soucis. Si c'est ce qui vous importe, alors les slashs sont acceptables, mais pas les backslashes.

6voto

Jens Gustedt Points 40410

La barre oblique noire est un comportement indéfini et même avec une barre oblique, il faut être prudent. La norme C99 stipule :

Si les caractères ', \, ", //, ou /* apparaissent dans la séquence entre les délimiteurs < et >, le comportement est indéfini. indéfini. De même, si les caractères caractères ', \, // ou /* apparaissent dans la la séquence entre les délimiteurs ", le comportement est indéfini.

1voto

Alan Stokes Points 9095

Utilisez toujours des barres obliques - elles fonctionnent sur davantage de plateformes. Les barres obliques inversées provoquent techniquement un comportement non défini dans C++03 (2.8/2 dans la norme).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X