Aquí está el código compilado en dev c ++ windows:
#include <stdio.h>
int main() {
int x = 5;
printf("%d and ", sizeof(x++)); // note 1
printf("%d\n", x); // note 2
return 0;
}
Espero x
ser 6 después de ejecutar la nota 1 . Sin embargo, la salida es:
4 and 5
¿Alguien puede explicar por qué x
no se incrementa después de la nota 1 ?
VLAs
que ninguno de los otros lo haga.Respuestas:
Del estándar C99 (el énfasis es mío)
fuente
N
desde stdin y makeint array[N]
. Esta es una de las características de C99, no disponible en C ++.sizeof(int[++x])
(realmente, realmente una mala idea, de todos modos) se++
podría evaluar.gcc
,clang
y al ideone.com/Pf7iFsizeof
es un operador en tiempo de compilación, por lo que en el momento de la compilaciónsizeof
y su operando se reemplaza por el valor del resultado. El operando no se evalúa (excepto cuando es una matriz de longitud variable); solo importa el tipo de resultado.Salida:
como
short
ocupa 2 bytes en mi máquina.Cambiar el tipo de retorno de la función a
double
:dará
8
como salida.fuente
sizeof(foo)
intenta realmente descubrir el tamaño de una expresión en tiempo de compilación:6.5.3.4:
En resumen: matrices de longitud variable, ejecutar en tiempo de ejecución. (Nota: Las matrices de longitud variable son una característica específica, no matrices asignadas con
malloc(3)
). De lo contrario, solo se calcula el tipo de expresión, y eso en tiempo de compilación.fuente
sizeof
es un operador integrado en tiempo de compilación y no es una función. Esto se vuelve muy claro en los casos en que puede usarlo sin el paréntesis:fuente
sizeof
operador no es un operador de tiempo de compilación, solo tiene que darle un VLA para resolver esto.Nota
Esta respuesta se fusionó a partir de un duplicado, lo que explica la fecha de retraso.
Original
A excepción de las matrices de longitud variable sizeof no evalúa sus argumentos. Podemos ver esto en el borrador de la sección estándar C99
6.5.3.4
El tamaño del párrafo 2 del operador que dice:Un comentario ( ahora eliminado ) preguntaba si algo como esto se evaluaría en tiempo de ejecución:
y de hecho lo haría, algo como esto también funcionaría ( verlos a ambos en vivo ):
ya que ambos son matrices de longitud variable. Aunque, no veo mucho uso práctico en ninguno de los dos.
Nota, las matrices de longitud variable están cubiertos en el proyecto de norma C99 sección
6.7.5.2
de matriz declaradores párrafo 4 :Actualizar
En C11, la respuesta cambia para el caso de VLA, en ciertos casos no se especifica si la expresión de tamaño se evalúa o no. De la sección
6.7.6.2
Declaradores de matriz que dice:Por ejemplo, en un caso como este ( verlo en vivo ):
fuente
sizeof
es efectivamente una macro: no crea código, sino que calcula previamente el valor esperado y lo deposita directamente en el código. Tenga en cuenta que este fue el único comportamiento hasta C99, ya que los VBA no existían (nunca había oído hablar de ellos hasta esta respuesta, ¡créanlo o no!)sizeof (char[x++]);
usaría el valor dex
para otra cosa que no sea determinar el valor de la expresiónx++
y el nuevo valor parax
, los cuales son normales con ese operador?char[x++]
es un VLA. se ve efectivamente como unchar*
para mis ojos desconocidos.Como el operando del
sizeof
operador no se evalúa, puede hacer esto:Demostración en línea: http://ideone.com/S8e2Y
Es decir, no necesita definir la función
f
si solo se usasizeof
. Esta técnica se usa principalmente en la metaprogramación de plantillas de C ++, ya que incluso en C ++, el operando desizeof
no se evalúa.¿Por qué funciona esto? Funciona porque el
sizeof
operador no opera según el valor , sino que funciona según el tipo de expresión. Entonces, cuando escribesizeof(f())
, opera sobre el tipo de expresiónf()
, y que no es más que el tipo de retorno de la funciónf
. El tipo de retorno es siempre el mismo, sin importar qué valor devolvería la función si realmente se ejecuta.En C ++, puedes incluso esto:
Sin embargo, parece que, en primer lugar
sizeof
, estoy creando una instancia deA
, escribiendoA()
, y luego llamando a la funciónf
en la instancia, escribiendoA().f()
, pero no sucede tal cosa.Demostración: http://ideone.com/egPMi
Aquí hay otro tema que explica algunas otras propiedades interesantes de
sizeof
:fuente
La ejecución no puede ocurrir durante la compilación. Entonces
++i
/i++
no sucederá. Tampocosizeof(foo())
ejecutará la función pero devolverá el tipo correcto.fuente
sizeof
es una expresión constante de tiempo de compilación"sizeof
se ejecuta en tiempo de compilación, perox++
solo se puede evaluar en tiempo de ejecución. Para resolver esto, el estándar C ++ dicta que el operando desizeof
no se evalúa. El estándar C dice:fuente
sizeof()
El operador solo da el tamaño del tipo de datos, no evalúa los elementos internos.fuente
sizeof()
operador actúa de forma recursiva y obtendrá el tamaño en bytes de todos los elementos de un contenedor, miembros de una clase o estructura, etc. Puede probarlo usted mismo muy fácilmente creando una clase simple con unos pocos miembros y llamandosizeof()
en él. (Sin embargo, cualquier cosa allí que sea un puntero no puede ver el tamaño, solo el tamaño del puntero). Esto sucede todo en el momento de la compilación, como dijeron otros comentaristas: las expresiones dentro delsizeof()
no se evalúan.