El siguiente código (tomado de aquí ):
int* ptr = int();
compila en Visual C ++ y valor-inicializa el puntero.
¿Cómo es eso posible? Me refiero a que int()
produce un objeto de tipo int
y no puedo asignar un int
puntero.
¿Cómo es que el código anterior no es ilegal?
c++
visual-c++
pointers
initialization
built-in-types
diente filoso
fuente
fuente
int()
produce el valor construido valor deint
(que creo que es una cosa especificada en C ++ 03) y el valor predeterminado deint
es0
. Esto es equivalente aint *ptr = 0;
NULL
pudiera ser un valor distinto de cero. Dije que podría ser cualquier constante entera de valor cero (que incluyeint()
).Respuestas:
int()
es una expresión constante con un valor de 0, por lo que es una forma válida de producir una constante de puntero nulo. En última instancia, es solo una forma ligeramente diferente de decirint *ptr = NULL;
fuente
nullptr
, que puede usar en lugar de0
oNULL
en el nuevo código.0
podría significar una constante de puntero nulo o el número 0, mientras quenullptr
es obvio una constante de puntero nulo. Además, como dijo Jamin, también tiene "controles adicionales en tiempo de compilación". Intente pensar antes de escribir.Porque
int()
cede0
, que es intercambiable conNULL
.NULL
en sí se define como0
, a diferencia de C,NULL
que es(void *) 0
.Tenga en cuenta que esto sería un error:
int* ptr = int(5);
y esto seguirá funcionando:
int* ptr = int(0);
0
es un valor constante especial y, como tal, puede tratarse como un valor de puntero. Expresiones constantes que dan0
como resultado ,1 - 1
como también se permiten como constantes de puntero nulo.fuente
(void *)0
. Es simplemente una implementación definida "expresión constante entera con el valor 0, o una expresión convertida al tipo void *".NULL
como(void*)0
; siempre fue0
(o tal vez0L
). (Pero luego, cuando C90 se hizo(void*)0
legal en C, ya estaba usando C ++.)#if !defined(__cplusplus) \n #define NULL ((void*)0) \n #else \n #define NULL (0)
versión de Linux, libio.h contiene: la versión actual de gcc en ubuntu es 4.5, en nuestro sistema es 4.0.0
es un literal especial", solo porque es una expresión constante y tiene el valor especial 0.(1-1)
es igualmente especial, también es una constante de puntero nulo, y también lo esint()
. El hecho de0
ser literal es condición suficiente pero no necesaria para ser una expresión constante. Algo comostrlen("")
, aunque también tiene el valor especial0
, no es una expresión constante y, por lo tanto, no es una constante de puntero nulo.0
, no del0
literal.La expresión se
int()
evalúa como un entero constante inicializado por defecto, que es el valor 0. Ese valor es especial: se utiliza para inicializar un puntero al estado NULL.fuente
int f() { return 0; }
, la expresiónf()
produce el valor 0, pero no se puede usar para inicializar un puntero.De n3290 (C ++ 03 usa texto similar), 4.10 Conversiones de puntero [conv.ptr] párrafo 1 (el énfasis es mío):
int()
es una expresión constante integral prvalue de tipo entero que se evalúa a cero (¡eso es un bocado!), y por lo tanto se puede usar para inicializar un tipo de puntero. Como puede ver,0
no es la única expresión integral con mayúsculas especiales.fuente
Bueno, int no es un objeto.
Creo que lo que está sucediendo aquí es que le estás diciendo al int * que apunte a alguna dirección de memoria determinada por int ()
así que si int () crea 0, int * apuntará a la dirección de memoria 0
fuente
int()
ciertamente es un objeto.int()
. Definirint i;
, entonces sin duda,i
es un objeto.int
es un tipo, no un objeto. Ya sea queint()
produzca un objeto o simplemente un rvalue, no afecta nada de lo que nadie haya dicho en otra parte.