2012-05-04 13 views
7

Eche un vistazo a este pequeño programa.C++ 11 incluye <cstdlib> en momentos en que C++ 03 no?

#include <iostream> 

int main(){ 

    int var = atoi("-99");  //convert string to int 
    var = abs(var);    //takes absolute value 
    std::cout << var+1 <<'\n'; //outputs 100 

    return EXIT_SUCCESS; 
} 

Compilación crea los siguientes mensajes de error:

$ g++ -o main main.cpp 
main.cpp: In function ‘int main()’: 
main.cpp:5:13: error: ‘atoi’ was not declared in this scope 
main.cpp:6:16: error: ‘abs’ was not declared in this scope 
main.cpp:9:10: error: ‘EXIT_SUCCESS’ was not declared in this scope 

comprensible. Todos estos existen en el encabezado "cstdlib" que no incluí.
Sin embargo, compilar con:

$ g++ -std=c++0x -o main main.cpp 

crea ningún problema.


mirando a la fuente de la "cstdlib" de cabecera, veo el siguiente código en la parte inferior:

#ifdef __GXX_EXPERIMENTAL_CXX0X__ 
# if defined(_GLIBCXX_INCLUDE_AS_TR1) 
# error C++0x header cannot be included from TR1 header 
# endif 
# if defined(_GLIBCXX_INCLUDE_AS_CXX0X) 
# include <tr1_impl/cstdlib> 
# else 
# define _GLIBCXX_INCLUDE_AS_CXX0X 
# define _GLIBCXX_BEGIN_NAMESPACE_TR1 
# define _GLIBCXX_END_NAMESPACE_TR1 
# define _GLIBCXX_TR1 
# include <tr1_impl/cstdlib> 
# undef _GLIBCXX_TR1 
# undef _GLIBCXX_END_NAMESPACE_TR1 
# undef _GLIBCXX_BEGIN_NAMESPACE_TR1 
# undef _GLIBCXX_INCLUDE_AS_CXX0X 
# endif 
#endif 

no estoy seguro si eso es relevante o no .. archivo de cabecera completa código here

mi última pregunta es, ¿el nuevo estándar garantiza que todos los cstdlib se incluirán en un espacio de nombres global cuando se incluye iostream?

No encuentro ninguna documentación al respecto. Me parece así, ¿te parece así?

gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1 
+3

Por cierto, este título era totalmente engañoso. C++ 11 ** es ** C++. No es un nuevo idioma separado. –

Respuesta

15

mi última pregunta es, ¿la nueva garantía estándar que todos cstdlib serán llevados in en un espacio de nombres global cuando se incluye iostream?

No. Usted debería #include usted mismo si necesita su funcionalidad. Si lo obtiene "gratis" con <iostream>, eso es un signo de que su encabezado <iostream> lo requiere, pero luego está confiando en un detalle de implementación de su biblioteca C++.

Btw., #include <cstdlib> no garantiza que lleve las funciones C al espacio de nombre global (aunque comúnmente lo hace en las implementaciones de C++); se garantiza que ponerlos en el espacio de nombres std:

Excepto según se indica en las cláusulas 18 a 30 y el Anexo D, el contenido de cada cabecera cname será el mismo que el de la cabecera correspondiente name.h, como se especifica en la biblioteca estándar C (1.2) o la C Unicode TR, según corresponda, como si fuera por inclusión. Sin embargo, en la biblioteca estándar de C++, las declaraciones (excepto los nombres que se definen como macros en C) se encuentran dentro del ámbito de espacio de nombres (3.3.6) del espacio de nombres std. No se especifica si estos nombres se declaran primero dentro del ámbito de espacio de nombres global y luego se inyectan en el espacio de nombres std mediante using -declarations explícitas (7.3.3).

(Estándar, la sección 17.6.1.2)

+0

eso es extraño, no tuve que buscar atoi –

+1

@Xploit: no importa mi comentario anterior.'' pone 'atoi' en el espacio de nombres' std'; si el suyo también lo coloca en el espacio de nombres global, entonces esa es una extensión específica de la plataforma. –

+0

@larsmars Eso no es una característica, es un error. Es una contaminación involuntaria del espacio de nombres global, que es notoriamente difícil de evitar como escritor de la biblioteca. gcc hace un buen trabajo para dar cuerpo a esas contaminaciones. Por cierto, esa es una fuente importante de mala compilación de paquetes de software con la versión más nueva de gcc, que hasta entonces compilaba bien. – hirschhornsalz

Cuestiones relacionadas