web-dev-qa-db-fra.com

La barre oblique inverse est-elle acceptable dans les directives C # et C++ #include?

Il existe deux séparateurs de chemins couramment utilisés: le slash avant et le pseudonyme de DOS. Repose en paix, deux points Mac classique. S'ils sont utilisés dans une directive #include, sont-ils égaux selon les règles des normes C++ 11, C++ 03 et C99?

38
Potatoswatter

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 indé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 indéfini.)

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

L'apparition de l'un des caractères 'ou\ou de l'une des séquences de caractères/* ou // dans une séquence q-char ou une séquence h-char est prise en charge de manière conditionnelle avec la sémantique définie par l'implémentation, de même que l'apparition de le caractère "dans une séquence h-char.

(note de bas de page: ainsi, une séquence de caractères ressemblant à 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, en fonction de l'implémentation.)

Par conséquent, bien que tout compilateur puisse choisir de prendre en charge une barre oblique inversée dans un chemin #include, il est peu probable qu'un fournisseur de compilateur ne prenne pas en charge la barre oblique inversée et des barres obliques inverses risquent de bloquer certaines implémentations en raison de la formation de codes d'échappement. (Edit: apparemment, MSVC nécessitait auparavant une barre oblique inversée. Peut-être que d'autres sur les plates-formes dérivées de DOS étaient similaires. Hmmm… que puis-je dire?)

C++ 11 semble assouplir les règles, mais "pris en charge de manière conditionnelle" n'est pas vraiment meilleur que "provoque un comportement indéfini". Le changement fait plus pour refléter l’existence de certains compilateurs populaires que pour décrire une norme portable.

Bien entendu, aucune de ces normes ne dit qu'il existe des chemins. Il existe systèmes de fichiers sans aucun chemin! Cependant, de nombreuses bibliothèques supposent des chemins d'accès, y compris POSIX et Boost, il est donc raisonnable de vouloir un moyen portable de faire référence à des fichiers dans des sous-répertoires.

47
Potatoswatter

La barre oblique est la bonne façon; le pré-compilateur fera tout ce qu'il faut sur chaque plate-forme pour obtenir le bon fichier.

7
trojanfoe

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

Les barres obliques sont acceptables des deux côtés, les barres obliques inverses ne le sont pas.

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

Mais ce n'est pas pertinent pour la plupart des gens. Si vous écrivez en C++ 1x, où les barres obliques inverses sont prises en charge de manière conditionnelle et que la plate-forme pour laquelle vous codez les prend en charge, elles sont acceptables. Et si vous écrivez un "dialecte étendu" de C99/C++ 03/C1x qui définit des barres obliques inverses, la même affaire. Et, plus important encore, cette notion d '"acceptable" n'a de toute façon pas de sens dans la plupart des cas. Aucune des normes C/C++ ne définit ce que signifient les barres obliques (ou ce que signifient les barres obliques inverses lorsqu'elles sont prises en charge de manière conditionnelle). Les noms d'en-tête sont mappés aux fichiers source d'une manière définie par l'implémentation, période. 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: ni l'un ni l'autre n'est portable. Si vous voulez écrire du code réellement portable, vous ne pouvez pas utiliser les hiérarchies de fichiers d'en-tête. En fait, votre meilleur choix est d'écrire tout dans un seul fichier source et de ne pas inclure rien, sauf les en-têtes standard.

Cependant, dans le monde réel, les gens veulent souvent "assez portable", pas "strictement portable". La norme POSIX prescrit ce que signifient les barres obliques, 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 intégrées et mobiles telles que Symbian, etc., traitent les barres obliques de la manière POSIX Directives C/C++ #include. Toute plate-forme qui ne le fera pas n'aura probablement aucun moyen pour vous d'obtenir votre arborescence source, de traiter votre fichier makefile/etc., Etc., de sorte que les directives #include soient le moindre de vos soucis. Si c'est ce qui vous intéresse, les barres obliques sont acceptables, mais les barres obliques inverses ne le sont pas.

5
abarnert

Blackslash est un comportement indéfini et même avec une barre oblique, vous devez faire attention. La norme C99 stipule:

Si les caractères ', \, ", // ou /* Apparaissent dans la séquence entre les délimiteurs < Et>, le comportement est Non défini. caractères ', \, // ou/* apparaissent dans la séquence entre les "délimiteurs, le comportement est indéfini.

5
Jens Gustedt

Utilisez toujours des barres obliques: elles fonctionnent sur plusieurs plates-formes. La barre oblique inverse provoque techniquement un comportement indéfini en C++ 03 (2.8/2 dans la norme).

1
Alan Stokes

La norme dit pour #include que:

recherche dans une séquence d'emplacements définis par l'implémentation pour un en-tête identifié uniquement par la séquence spécifiée entre les délimiteurs et provoque le remplacement de cette directive par le contenu complet de . La manière dont les espaces sont spécifiés ou l'en-tête Identifié est définie par l'implémentation.

Notez la dernière phrase.

0
Neil Butterworth