Implementación del operador sizeof

5 minutos de lectura

avatar de usuario
Raghu Srikanth Reddy

He intentado implementar el operador sizeof. lo he hecho de esta forma:

#define my_sizeof(x) ((&x + 1) - &x)

Pero siempre terminaba dando el resultado como ‘1’ para cualquiera de los tipos de datos.

Luego lo busqué en Google y encontré el siguiente código:

#define my_size(x) ((char *)(&x + 1) - (char *)&x)

Y el código está funcionando si es encasillado, no entiendo por qué. Este código también está ACOLCHANDO una ESTRUCTURA perfectamente.

También está trabajando para:

#define my_sizeof(x) (unsigned int)(&x + 1) - (unsigned int)(&x)

¿Alguien puede explicar cómo funciona si está encasillado?

  • Casting a unsigned int es una mala idea uintptr_t es mejor pero aún implica una conversión implícita molesta pero inevitable.

    – Pascal Cuoq

    5 de enero de 2013 a las 11:12


  • tu básicamente no poder implementar sizeof. Es una parte esencial del lenguaje C.

    – Basile Starynkevitch

    2 de abril de 2019 a las 7:24

El resultado de la resta del puntero está en elementos y no en bytes. Así, la primera expresión se evalúa como 1 por definición.

Aparte de esto, deberías usar paréntesis en las macros:

#define my_sizeof(x) ((&x + 1) - &x)
#define my_sizeof(x) ((char *)(&x + 1) - (char *)&x)

De lo contrario, intentar usar my_sizeof() en una expresión puede dar lugar a errores.

  • Las macros no tienen remedio como medio de reemplazar sizeof. Ellos evalúan el argumento (dos veces también)… Piensa en my_sizeof(x++).

    – Estera

    5 de enero de 2013 a las 11:09

avatar de usuario
Basile Starynkevitch

los sizeof El operador es parte de la especificación del lenguaje C (y C++) y se implementa dentro del compilador (el front-end). No hay forma de implementarlo con otras construcciones C (a menos que use extensiones GCC como tipo de) porque puede aceptar tipos o expresiones como operandos, sin tener ningún efecto secundario (p. ej. sizeof((i>1)?i:(1/i)) no se estrellará cuando i==0 pero tu macro my_sizeof chocaría con una división por cero). Ver también Directrices de codificación Cy wikipedia.

deberías entender c aritmética de punteros. Véase, por ejemplo, esta pregunta. La diferencia de puntero se expresa en elementos, no en bytes.

avatar de usuario
Kuppappa DH

#define my_sizeof(x) ((char *)(&x + 1) - (char *)&x)

Esta my_sizeof() macro no funcionará en los siguientes casos:

  1. sizeof 1 – 4 bytes (para una plataforma con 4 bytes int)
    my_sizeof(1) – no compilará en absoluto.

  2. sizeof (int) – 4 bytes (para una plataforma con 4 bytes int)
    my_sizeof(int) – no compilará código en absoluto.

Funcionará solo para variables. No funcionará para tipos de datos como int, float, char etc., para literales como 2, 3.4, 'A'etc., ni para expresiones rvalue como a+b o foo().

  • Este sería un gran comentario, porque no responde a la pregunta formulada, pero es una “crítica constructiva que guía al autor a mejorar la publicación”…

    – autista

    3 de febrero de 2016 a las 18:24

  • tampoco informará correctamente el tamaño debido a la alineación. en el ejemplo, una variable de tamaño de 6 bytes informará 8.

    -Ol Sen

    6 de enero de 2021 a las 16:04


  • @OlSen Si &x + 1 son 8 bytes pasados &xluego los sizeof(x) es de hecho 8: “Para la resta de punteros, el resultado de la diferencia entre los punteros de caracteres se divide de manera similar por el tamaño del objeto apuntado originalmente.”

    –Andrew Henle

    12 de febrero a las 11:59


#define my_sizeof(x) ((&x + 1) - &x)

&x da la dirección de la variable (digamos doble x) declarada en el programa e incrementándola en 1 da la dirección donde se puede almacenar la siguiente variable del tipo x (aquí addr_of(x) + 8porque el tamaño de un doble es 8Byte).

La diferencia da como resultado que cuantas variables de tipo de x se puede almacenar en esa cantidad de memoria que obviamente será 1 para el tipo x (porque incrementarlo en 1 y sacar la diferencia es lo que hemos hecho).

#define my_size(x) ((char *)(&x + 1) - (char *)&x)

encasillándolo en char* y sacando la diferencia nos dirá cuantas variables de tipo char se puede almacenar en el espacio de memoria dado (la diferencia). Desde cada uno char requiere solo 1 byte de memoria, por lo tanto (cantidad de memoria)/1 dará la cantidad de bytes entre dos ubicaciones de memoria sucesivas del tipo de variable pasada a la macro y, por lo tanto, la cantidad de memoria que la variable de tipo x requiere

Pero no podrá pasar ningún literal a esta macro y conocer su tamaño.

Pero siempre terminaba dando el resultado como ‘1’ para cualquiera de los tipos de datos

Sí, así es como funciona la aritmética de punteros. Funciona en unidades del tipo al que se apunta. Así que lanzando a char * unidades de trabajo de charque es lo que quieres.

avatar de usuario
SakthiKarthik

Esto funcionará tanto para literales como para variables.

#define my_sizeof(x) (char*) (&(((__typeof__(x) *)0)[1])) - (char *)(&(((__typeof__(x) *)0)[0]))

avatar de usuario
CY

Busqué esto ayer, y encontré esta macro:

#define mysizeof(X)  ((X*)0+1)

Que expande X solo una vez (sin error como doble evaluación de expresión como x ++), y funciona bien hasta ahora.

  • Aunque esta macro no tuvo ningún error con mis pruebas con estructuras, el uso del operador cubre situaciones mucho más generales. Por ejemplo, mysizeof(2) no puede compilar, pero sizeof(2) produce 4, el tamaño del entero.

    – CY

    26 de junio de 2018 a las 14:48


  • Expresión esperada.

    -Ol Sen

    06/01/2021 a las 16:50

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad