2010-01-22 11 views
5

El C++ Programming Language: estados de edición especial en la página 431 que ...Ámbito de bibliotecas de C en C++ - <X.h> vs <cX>

For every header <X.h> defining part of the C standard library in the global namespace and also in namespace std, there is a header <cX> defining the same names in the std namespace only.

Sin embargo, cuando se utiliza cabeceras de C en el CX> estilo < , No necesito calificar el espacio de nombres. Por ejemplo ...

#include <cmath> 
void f() { 
    double var = sqrt(17); 
} 

Esto compilaría bien. Aunque el libro dice que usar el encabezado < cX> define los nombres solo en el espacio de nombres std, puede usar esos nombres sin calificar el espacio de nombres. ¿Que me estoy perdiendo aqui?

P.S. Uso del compilador GNU.GCC

+1

¿Cuál es su compilador? Muchos compiladores no se ajustan exactamente – Mark

+0

Estoy usando el compilador GNU.GCC – Anonymous

+0

¿Qué versión? 3.x es demasiado viejo IIRC. – MSalters

Respuesta

9

Stephan T. Lavavej, un miembro del equipo de MSVC, aborda la realidad de esta situación (y algunas de las mejoras a la norma) en este comentario en una de sus publicaciones en blogs (http://blogs.msdn.com/vcblog/archive/2008/08/28/the-mallocator.aspx#8904359):

> también, <cstddef>, <cstdlib>, y std::size_t etc. ¡deben usarse!

Solía ​​tener mucho cuidado con eso.C++ 98 tuvo un espléndido sueño en el que <cfoo> declararía todo dentro del espacio de nombres std, y <foo.h> incluiría <cfoo> y luego arrastraría todo al espacio de nombres global con use-declarations. (Esto es D.5 [depr.c.headers].)

Esto fue ignorado por muchos implementadores (algunos de los cuales tenían muy poco control sobre los encabezados de C Standard Library). Entonces, C++ 0x ha sido cambiado para que coincida con la realidad. A partir del documento de trabajo N2723, http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2723.pdf, ahora <cfoo> se garantiza que declarará todo dentro del espacio de nombres estándar, y puede o no declarar cosas dentro del espacio de nombres global. <foo.h> es lo opuesto: se garantiza que declara todo dentro del espacio de nombres global, y puede o no declarar cosas dentro del espacio de nombres estándar.

En realidad y en C++ 0x, incluido <cfoo>, no hay ninguna protección contra todo lo que se declare en el espacio de nombres global de todos modos. Es por eso que estoy dejando de molestarme con <cfoo>.

Esto era Library Issue 456, http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456.

(C++ 0x todavía desaprueba las <foo.h> cabeceras de la biblioteca estándar de C, que es hilarante.)

Estoy de acuerdo al 100% con Lavavej, excepto que nunca he tratado de ser muy cuidadoso con usando los encabezados de estilo <cfoo> incluso cuando comencé a usar C++ - los C estándar estaban muy arraigados - y nunca hubo un problema en el mundo real al usarlos (y aparentemente nunca hubo ningún beneficio en el mundo real al usar los encabezados de estilo <cfoo>).

+0

Entonces, ¿usar los encabezados de estilo no debería dañar la portabilidad? – Anonymous

+0

No, el uso de los encabezados '' no debería perjudicar la portabilidad. No debería contar con que los nombres de ese encabezado se excluyan del espacio de nombres global. Porque en realidad hay muchas posibilidades de que estén allí de todos modos. –

+8

Soy un tipo raro de purista y probablemente continuaré utilizando los encabezados '', pero es triste saberlo. – Omnifarious

0

Probablemente falte el uso de un compilador que cumpla con los estándares (o el que usa esté configurado para ser compatible con el código preestablecido).

1

¿Por qué dices "Esto compilaría bien" cuando infringe el Estándar? ¿Quién te permite usar esos nombres sin calificar el espacio de nombres? ¿Has probado esto en una implementación particular y descubrió que funciona?

Recomiendo enfáticamente que no se use alguna característica particular no estándar porque funciona en el compilador de su elección. Tales cosas se rompen fácilmente, tal vez con una versión posterior del mismo compilador.

+0

+1 Funciona! = Se debe esperar que funcione. –

6

La regla para las bibliotecas de C se diferencia de C++ bibliotecas para espacios de nombres

gcc interpreta el estándar en Gcc docs como

El estándar especifica que si se incluye la cabecera de estilo C (< math.h > en este caso), los símbolos estarán disponibles en el espacio de nombres global y quizás en el espacio de nombres std :: (pero esto ya no es un requisito firme). Por otro lado, incluido el encabezado de estilo C++ (< cmath>) garantiza que las entidades se encontrarán en el espacio de nombres std y quizás en el espacio de nombres global.

En el proyecto de C0X ++ spec se dice en la sección 17.6.2.3 encabezados

Es sin especificar si estos nombres se declaran primero dentro del ámbito espacio de nombres global y luego se inyectan en namespace std por el uso explícito -declaraciones

4

Es difícil solucionar esto sin implementar la biblioteca C dos veces. Ver DR 456, que básicamente propone renunciar al problema.

+0

+1 para vincular a la RD. –