how from code c++ include c++-faq

from - ¿Debo incluir<xxxx.h> o<cxxxx> en programas C++?



extern c (2)

Considere los siguientes programas:

Muestra 1:

#include<stdio.h> int main() { printf("Hello World"); return 0; }

Muestra 2:

#include<cstdio> int main() { printf("Hello World"); return 0; }

Ambos funcionan como se esperaba. Entonces, ¿qué uso es más apropiado? La respuesta es: ¡Ninguno! ¿Sorprendido? Sigue leyendo.

La biblioteca estándar de C ++ proporciona todos los encabezados C estándar por razones de compatibilidad, mientras que C ++ como lenguaje también proporciona todos los encabezados equivalentes. Como una convención,

  • Ningún encabezado de biblioteca estándar de C ++ (aparte de los que se incluyen para compatibilidad C) tiene extensiones de archivo, y
  • Todo el equivalente en C ++ de los encabezados C comienza con cxxxxx .

El Estándar C ++ menciona esto bajo las características de Compatibilidad del Anexo D (normativas) :

§2 menciona el punto distintivo importante. Esta regla aplicada a los ejemplos anteriores significa:

  • Incluir cstdio importa los nombres de los símbolos en el espacio de nombres std y posiblemente en el espacio de nombres Global.
  • La inclusión de stdio.h importa los nombres de los símbolos en el espacio de nombres Global y posiblemente en el espacio de nombres std.

Permítanos aplicar esta regla a nuestros códigos de muestra y medir los pros y los contras:

Muestra 1: Esto trae todos los símbolos de stdio.h en el espacio de nombres global. La ventaja es que puede usar los símbolos sin ninguna calificación ya que se importan en el espacio de nombres global. Lo malo es que terminas contaminando el espacio de nombres global con muchos nombres de símbolos que probablemente nunca usarás. Esto podría llevar a una colisión de nombre de símbolo. En C ++ siempre considere el espacio de nombres global como un campo minado y evítelo tanto como sea posible.

Ejemplo 2: esta es una práctica muy mala porque no hay garantía de que la implementación ponga los símbolos en el espacio de nombres global, el estándar simplemente no exige hacerlo. Simplemente confiamos en el comportamiento de una implementación particular del compilador. No podemos ni debemos suponer que todos los compiladores lo harán. Tan estrictamente hablando, el programa no está aprobado de forma estándar y este uso no es portátil en todas las implementaciones.

Entonces, ¿cuál es el uso correcto?

El uso correcto es usar cstdio y calificar completamente los nombres de los símbolos o bien ponerlos en contexto con el using declaraciones . Esto garantiza que todos los símbolos que usamos están presentes en el std nombres std y no estamos contaminando el espacio de nombres global. Ejemplo de uso correcto:

Muestra 3:

#include<cstdio> using std::printf; int main() { printf("Hello World"); return 0; }

Tenga en cuenta que la directiva que using namespace std; , especialmente en un encabezado, no es una buena opción y siempre debe usar el using declaraciones.

Tenga en cuenta que consideramos stdio.h vs. cstdio aquí solo como un caso de uso de muestra, en la práctica se aplica a la mayoría de los encabezados cxxxx y xxxx.h , excepto algunos como <math.h> y <cmath> .

  • ¿Qué debería incluir en los programas C ++, stdio.h o cstdio ? ¿y por qué?
  • ¿Por qué dos archivos de encabezado que proporcionan la misma funcionalidad?
  • ¿Qué dice la norma con respecto a esto?
  • ¿Cómo debería incluir otros encabezados similares? ¿Existe alguna regla base que deba seguir?

Como esta publicación es un poco vieja, quería compartir lo siguiente:

Mirando el código:

Using X.h // Compatible with C language standard --------------- #include <X.h> int main() { // Invoke X''s corresponding function return 0; } Using X // Not compatible with C language standard -------------- #include <X> int main() { // Invoke X''s corresponding function return 0; }

¡Ambos compilan y ejecutan bien!

¿Cuál es mejor en C ++?

Con respecto a las especificaciones de C++11 y C++17 :

C.5.1 (sección del documento C ++ 17)
Modificaciones a los encabezados [diff.mods.to.headers]

  1. Para la compatibilidad con la biblioteca estándar C, la biblioteca estándar C ++ proporciona los encabezados C enumerados en D.5, pero su uso está en desuso en C ++.

  2. No hay encabezados C ++ para los encabezados C <stdatomic.h> , <stdnoreturn.h> y <threads.h> , ni los encabezados C son parte de C ++.

  3. Los encabezados C ++ <ccomplex> (D.4.1) y <ctgmath> (D.4.4), así como sus correspondientes encabezados C <tgmath.h> y <tgmath.h> , no contienen ningún contenido de la C biblioteca estándar y, en su lugar, simplemente incluye otros encabezados de la biblioteca estándar de C ++.

D.5 C encabezados de biblioteca estándar [depr.c.headers] 1. Para compatibilidad con la biblioteca estándar C, la biblioteca estándar de C ++ proporciona los encabezados C que se muestran en la Tabla 141.

Los documentos de especificaciones estándar de C ++ 11 y C ++ 17 indican que el uso de <Xh> sigue siendo compatible con el estándar C, aunque su uso se considera obsoleto .

En cuanto a la propuesta estándar de C ++ 20

Están revisando "no preponderando" el uso de los encabezados de la biblioteca C en C ++ 20. <Xh> aparecen resaltados en verde. La desactivación de C ++ 11 y C ++ 17, a partir de ahora, se indica como una "recomendación débil" y se muestra a continuación un "ajuste" para mantener los " encabezados de biblioteca estándar C " (c.headers) :

"Los encabezados básicos de la biblioteca C son una característica esencial de compatibilidad, y no irán a ningún lado pronto". (del documento de revisión C ++ 20 )

Estándar D.5 C
encabezados de biblioteca [depr.c.headers]

Recomendación débil: Además de lo anterior, también elimine los encabezados C correspondientes del estándar C ++, al igual que no tenemos los <stdatomic.h> , <stdnoreturn.h> , o <threads.h> . Como se indicó anteriormente, pero con los siguientes ajustes: 20.5.5.2.1 C cabeceras de biblioteca estándar [c.headers]

Para compatibilidad con la biblioteca estándar C, la biblioteca estándar C ++ proporciona los encabezados C que se muestran en la Tabla 141. Tabla 141 - Cabeceras en C

<assert.h> <inttypes.h> <signal.h> <stdio.h> <wchar.h> <complex.h> <iso646.h> <stdalign.h> <stdlib.h> <wctype.h> <ctype.h> <limits.h> <stdarg.h> <string.h> <errno.h> <locale.h> <stdbool.h> <tgmath.h> <fenv.h> <math.h> <stddef.h> <time.h> <float.h> <setjmp.h> <stdint.h> <uchar.h>

El encabezado <complex.h> comporta como si simplemente incluyera el encabezado. El encabezado <tgmath.h> comporta como si simplemente incluyera los encabezados <complex> y <cmath> .

Bjarne Stroustrup recomienda maximizar la interoperabilidad entre los lenguajes C y C ++ , al reducir las imcompatibilidades tanto como sea posible. Otros discuten lo contrario, ya que complica las cosas.

Entonces, parece que <Xh> no van a ningún lado . En definitiva, puedes usar ambos. Personalmente, tomaría la decisión de cuál usaría para reducir el código hacia atrás compatible con el código C o no.