Cuando se usan encabezados C en C++, ¿deberíamos usar funciones de std:: o del espacio de nombres global?


C es algo, no exactamente, un subconjunto de C++. Así que podemos usar la mayoría de las funciones/encabezados de C en C++ cambiando el nombre un poco (stdio.h a cstdio, stdlib.h a cstdlib).

Mi pregunta es en realidad una especie de semántica. En código C++ (usando la versión más reciente del compilador GCC), puedo llamar a printf("Hello world!); y std::printf("Hello world!); y funciona exactamente igual. Y en la referencia que estoy usando también aparece como std::printf("Hello world!);.

Mi pregunta es, ¿es preferible usar std::printf(); en C++? ¿Hay alguna diferencia?

Author: DeiDei, 2015-09-16

8 answers

Del estándar C++11 (énfasis mío):

D. 5 C standard library headers [depr.c. encabezados]

  1. Para compatibilidad con la biblioteca estándar C...
  2. Cada cabecera C, cada una de las cuales tiene un nombre de la forma nombre.h, se comporta como si cada nombre colocado en el estándar el espacio de nombres de la biblioteca por el encabezado cname correspondiente se coloca dentro del ámbito del espacio de nombres global. no se especifica si estos los nombres se declaran o definen primero dentro del ámbito del espacio de nombres (3.3.6) de el espacio de nombres std y luego se inyectan en el ámbito del espacio de nombres global mediante declaraciones de uso explícitas (7.3.3).
  3. Ejemplo: El encabezado <cstdlib> seguramente proporciona sus declaraciones y definiciones dentro del espacio de nombres std. También puede proporcionar estos nombres dentro del espacio de nombres global. El encabezado <stdlib.h> seguramente proporciona lo mismo declaraciones y definiciones dentro del espacio de nombres global, al igual que en el Estándar C. Se también puede proporcionar estos nombres dentro del espacio de nombres std.

Usando el " nombre.los encabezados h " están obsoletos, han sido identificados como candidatos para ser eliminados de futuras revisiones.

Por lo tanto, sugeriría incluir los encabezados "cname" y usar las declaraciones y definiciones del espacio de nombres std.

Si tiene que usar el "nombre.h " encabezados para algunos razones (está obsoleto, ver arriba), yo sugeriría usar las declaraciones y definiciones del espacio de nombres global.

En otras palabras: prefiera

#include <cstdio>

int main() {
    std::printf("Hello world\n");
}

Sobre

#include <stdio.h>

int main() {
    printf("Hello world\n");
}
 98
Author: sergej,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-02 20:12:27

<cmeow> siempre proporciona ::std::purr y puede o no puede proporcionar ::purr.

<meow.h> siempre proporciona ::purr y puede o no puede proporcionar ::std::purr.

Utilice el formulario que se garantiza que será proporcionado por el encabezado que incluye.

 76
Author: T.C.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-16 10:35:38

No, estás bien de cualquier manera.

La intención original era que las cabeceras <___.h> serían las versiones en C que ponen todo en el espacio de nombres global, y las cabeceras <c___> serían las versiones con C++, que colocan todo en el espacio de nombres std.

En la práctica, sin embargo, las versiones de C++ también ponen todo en el espacio de nombres global. Y no hay un consenso claro de que usar las versiones std:: es "lo correcto".

Así que básicamente, usa lo que prefieras. Lo más común es probablemente usar las funciones de biblioteca estándar de C en el espacio de nombres global (printf en lugar de std::printf), pero no hay mucha razón para considerar una "mejor" que la otra.

 7
Author: jalf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-16 10:39:03

La única diferencia es que en std::printf() al agregar std:: resolución de alcance, se asegurará de que alguien escriba una función con el mismo nombre en el futuro, lo que provocaría un conflicto de espacio de nombres. Ambos usos conducirán a exactamente las mismas llamadas a la API del sistema operativo (puede comprobarlo en Linux ejecutando strace your_program).

Me parece muy poco probable que alguien nombraría una función como esa, ya que printf() es una de las funciones más utilizadas por ahí. Además, en C++, iostream s son preffered sobre llamadas a cstdio funciones como printf.

 3
Author: syntagma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-16 10:38:11

Del estándar C++11:

Cada cabecera C, cada una de las cuales tiene un nombre del nombre del formulario.h, se comporta como si cada nombre colocado en el espacio de nombres de la biblioteca estándar por el el encabezado cname correspondiente se coloca dentro del espacio de nombres global alcance. No se especifica si estos nombres se declaran primero o definido dentro del ámbito de espacio de nombres (3.3.6) de la std de espacio de nombres y son luego se inyecta en el ámbito del espacio de nombres global declaraciones de uso (7.3.3).

Entonces, si usa <cstdio>, puede estar seguro de que printf estará en namespace std, y por lo tanto no en el espacio de nombres global.
El uso de un espacio de nombres global crea un conflicto de nombres. Este no es el modo C++.

Por lo tanto, estoy usando <cstdio> encabezados y le aconsejo que lo haga.

 3
Author: NeonMercury,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-16 10:38:46

De mi propia práctica: use std:: prefijos. De lo contrario un día abs te morderá muy dolorosamente en caso de que uses puntos flotantes.

No calificado abs se refiere a la función definida en int en algunas plataformas. En otros está sobrecargado. Sin embargo std::abs siempre está sobrecargado para todos los tipos.

 3
Author: eiennohito,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-17 14:16:22

Usar solo printf sin std:: podría generar algunos conflictos de nombres y es considerada una mala práctica por muchos desarrolladores de c++. Google es su amigo en este caso, pero aquí hay algunos enlaces, espero que esto ayude

¿Por qué" usar std de espacio de nombres " se considera una mala práctica? http://www.cplusplus.com/forum/beginner/61121 /

 2
Author: razvan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:25:31

En stdio

Esta es la versión en C++ del encabezado estándar de la biblioteca C @c stdio.h, y su contenido es (en su mayoría) el mismo que el encabezado, pero son todos contenido en el espacio de nombres @c std (excepto los nombres que están definidos como macros en C).

Así que no debería hacer ninguna diferencia.

 2
Author: anukul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-16 10:40:56