¿Es aceptable la barra invertida en las directivas C y C ++ #include?

Hay dos separadores de ruta de uso común: la barra diagonal inversa de Unix y la barra diagonal inversa de DOS. Descansa en paz, Classic Mac colon. Si se usa en una directiva #include, ¿son iguales bajo las reglas de los estándares C ++ 11, C ++ 03 y C99?

C99 dice (§6.4.7 / 3):

Si los caracteres ‘, \, “, // o / * aparecen en la secuencia entre los delimitadores , el comportamiento no está definido. Del mismo modo, si los caracteres’, \, // o / * aparecen en la secuencia entre los “delimitadores”, el comportamiento no está definido.

(nota al pie: por lo tanto, las secuencias de caracteres que se parecen a las secuencias de escape causan un comportamiento indefinido).

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

Si cualquiera de los caracteres ‘o \, o cualquiera de las secuencias de caracteres / * o // aparece en una secuencia de q-char o una secuencia de charla h, o el carácter “aparece en una secuencia de charla h, el el comportamiento no está definido

(nota al pie: por lo tanto, las secuencias de caracteres que se parecen a las secuencias de escape causan un comportamiento indefinido).

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

La aparición de cualquiera de los caracteres ‘o \ o de cualquiera de las secuencias de caracteres / * o // en una q-char-sequence o una h-char-sequence se admite condicionalmente con semántica definida por la implementación, como es la apariencia de el personaje “en una secuencia h-char.

(nota al pie: por lo tanto, una secuencia de caracteres que se asemeja a una secuencia de escape podría dar como resultado un error, ser interpretada como el carácter correspondiente a la secuencia de escape, o tener un significado completamente diferente, dependiendo de la implementación).

Por lo tanto, aunque cualquier comstackdor puede elegir admitir una barra diagonal inversa en una ruta #include , es poco probable que ningún proveedor de comstackdor admita la barra diagonal, y las barras invertidas probablemente disparen algunas implementaciones en virtud de la formación de códigos de escape. (Editar: aparentemente MSVC anteriormente requería barra invertida. Tal vez otros en plataformas derivadas de DOS eran similares. Hmmm … qué puedo decir).

C ++ 11 parece aflojar las reglas, pero “condicionalmente respaldado” no es significativamente mejor que “causa un comportamiento indefinido”. El cambio hace más para reflejar la existencia de ciertos comstackdores populares que para describir un estándar portátil.

Por supuesto, nada en ninguno de estos estándares dice que existan caminos. ¡Hay sistemas de archivos por ahí sin caminos! Sin embargo, muchas bibliotecas asumen nombres de rutas, incluidos POSIX y Boost, por lo que es razonable querer una forma portátil de consultar los archivos dentro de los subdirectorios.

Barra diagonal es la forma correcta; el precomstackdor hará lo que sea necesario en cada plataforma para llegar al archivo correcto.

Blackslash es un comportamiento indefinido e incluso con una barra oblicua debes tener cuidado. El estándar C99 establece:

Si los caracteres ‘, \, “, // o / * aparecen en la secuencia entre los delimitadores , el comportamiento no está definido. Del mismo modo, si los caracteres’, \, // o / * aparecen en la secuencia entre los “delimitadores”, el comportamiento no está definido.

Depende de lo que quiere decir con “aceptable”.

Hay dos sentidos en los que las barras son aceptables y las barras invertidas no.

Si está escribiendo C99, C ++ 03 o C1x, las barras diagonales inversas no están definidas, mientras que las barras diagonales son legales, por lo tanto, en este sentido, las barras diagonales inversas no son aceptables.

Pero esto es irrelevante para la mayoría de las personas. Si está escribiendo C ++ 1x, donde las barras diagonales inversas tienen soporte condicional, y la plataforma que está codificando las admite, son aceptables. Y si está escribiendo un “dialecto extendido” de C99 / C ++ 03 / C1x que define las barras diagonales inversas, el mismo trato. Y, más importante aún, esta noción de “aceptable” no tiene sentido en la mayoría de los casos de todos modos. Ninguno de los estándares C / C ++ define lo que significan las barras (o lo que significan las barras invertidas cuando reciben soporte condicional). Los nombres de encabezado se asignan a los archivos de origen de una manera definida por la implementación, punto. Si tiene una jerarquía de archivos, y está preguntando si utilizar barras diagonales inversas o barras diagonales para referirse a ellas de forma portátil en las directivas #include, la respuesta es: ninguna de ellas es portátil. Si desea escribir un código realmente portátil, no puede usar jerarquías de archivos de encabezado; de hecho, podría decirse que su mejor opción es escribir todo en un solo archivo de código fuente, y no #incluir nada excepto los encabezados estándar.

Sin embargo, en el mundo real, la gente a menudo quiere “lo suficientemente portátil”, no “estrictamente portátil”. El estándar POSIX exige lo que significan las barras, e incluso más allá de POSIX, la mayoría de las plataformas modernas -incluyendo Win32 (y Win64), los comstackdores cruzados para plataformas integradas y móviles como Symbian, etc.- tratan el estilo POSIX, al menos en la medida de lo posible. C / C ++ #include directivas. Cualquier plataforma que no lo haga, probablemente no tenga ninguna forma de obtener su árbol fuente, procesar su archivo MAKE / etc., por lo que las directivas #include serán la menor de sus preocupaciones. Si eso es lo que te importa, entonces las barras son aceptables, pero las barras invertidas no lo son.

El estándar dice para #include eso:

busca en una secuencia de lugares definidos por la implementación un encabezado identificado únicamente por la secuencia especificada entre los delimitadores, y hace que la sustitución de esa directiva por todo el contenido del encabezado. Cómo se especifican los lugares o el encabezado identificado está definido por la implementación.

Tenga en cuenta la última oración.

Utilice siempre barras diagonales: funcionan en más plataformas. El backslash técnicamente causa un comportamiento indefinido en C ++ 03 (2.8 / 2 en el estándar).

    Intereting Posts