Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

563
Vistas
¿Está bien definido el uso de sizeof en una variable donde existe un tipo del mismo nombre?

¿Este comportamiento está bien definido o no está definido / de alguna otra manera se definió en qué tamaño de foo (tipo de datos o identificador) estará sizeof ?

 typedef int foo; int main(int argc, char *argv[]) { char foo; printf ("%u\r\n", sizeof(foo)); return 0; }

Si está bien definido, ¿hay alguna manera de obtener el tamaño del tipo de datos foo sin declarar una variable de ese tipo solo para usar sizeof en él?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

¿Este comportamiento está bien definido o no está definido?

Este es un comportamiento bien definido.

en tu codigo

 printf ("%u\r\n", sizeof(foo));

foo es inequívoco. El foo local o interior "sombrea" (u oculta) el foo exterior . Entonces, es esencialmente

 printf ("%u\r\n", sizeof(char));

Para citar C11 , capítulo §6.2.1, "Alcances de los identificadores", ( énfasis mío )

Si un identificador designa dos entidades diferentes en el mismo espacio de nombres, los ámbitos pueden superponerse. Si es así, el alcance de una entidad (el alcance interno) terminará estrictamente antes que el alcance de la otra entidad (el alcance externo). Dentro del ámbito interior, el identificador designa la entidad declarada en el ámbito interior; la entidad declarada en el ámbito externo está oculta (y no visible) dentro del ámbito interno.

Ahora, para responder a la segunda parte,

Si está bien definido, ¿hay alguna manera de obtener el tamaño del tipo de datos foo sin declarar una variable de ese tipo para usar solo sizeof en él?

Bueno, un alcance del identificador foo interno comienza después de su definición (como una variable de tipo char ). Entonces, si usa foo (el tipo typedef ed) antes de la definición de la variable foo , en realidad verá la definición global, ya que hasta ese momento, la variable foo no está presente para "sombrear" el identificador global foo .

Como se mencionó en la otra respuesta del Sr. Purag , seguramente puede hacer algo como

 #include <stdio.h> typedef int foo; int main(void) { printf ("%zu\n", sizeof foo); /* will cosider the global */ char foo = 0; /* Global definition gets shadowed here*/ printf ("%zu\n", sizeof foo); /* The local definition of 'foo' is only visible*/ /* till the end of the block (function)*/ return 0; }

Dicho esto, como nota, el tipo de resultado del operador sizeof es size_t . Debería utilizar el especificador de formato %zu para imprimir el resultado.

over 4 years ago · Santiago Trujillo Denunciar

0

C no tiene una resolución de alcance explícita, por lo que los identificadores (nombres de variables, nombres de typedef, nombres de estructuras, etc., etc.) se pueden reutilizar y anular cuando se abre un nuevo alcance. Cuando se reutiliza un identificador, el contexto anterior contenido por ese identificador ya no es visible .

En su código particular, el alcance de typedef es global, por lo que typedef es visible en todas partes en su paquete de compilación. Sin embargo, abre un nuevo alcance con la declaración de la función, y en ese nuevo alcance define una variable que usa el mismo identificador que typedef . Ahora, ese identificador se refiere a la variable en lugar del tipo; es decir, hasta que finaliza el alcance de la variable (el final de la función), el typedef está completamente oculto.

Recuerde que C se compila de forma lineal, por lo que podría hacer algo como esto para evitar el blindaje que se produce:

 #include <stdio.h> typedef int foo; int main() { printf ("%zu\n", sizeof (foo)); /* #1 */ char foo; printf ("%zu\n", sizeof foo); /* #2 */ return 0; }

En el punto #1, tenga en cuenta que el alcance de la variable char foo aún no se ha abierto ya que el compilador no ha llegado a su declaración. (Todo lo que hará el compilador es asignar el espacio en la pila para la variable).

Entonces, el uso de foo en ese punto todavía se refiere al typedef definido globalmente.

En el momento en que presiona el n. ° 2, la variable se declara y la vida útil de la variable se inicia formalmente, lo que significa que el identificador ahora está en uso para una entidad diferente. Protege el alcance del bloque actual (iniciado por la declaración de la función) de la definición global de foo .

Este es un comportamiento bien documentado; hay un borrador del estándar C en línea, pero el estándar publicado debe comprarse. El borrador dice en la sección 6.2.1:

Si un identificador designa dos entidades diferentes en el mismo espacio de nombres, los ámbitos pueden superponerse. Si es así, el alcance de una entidad (el alcance interno) terminará estrictamente antes que el alcance de la otra entidad (el alcance externo). Dentro del ámbito interior, el identificador designa la entidad declarada en el ámbito interior; la entidad declarada en el ámbito externo está oculta (y no visible) dentro del ámbito interno. fuente

Tenga en cuenta que esto no es mágico ni nada... todo esto se hace en tiempo de compilación. El compilador tiene una tabla de identificadores y las cosas a las que hacen referencia, y los nuevos ámbitos crean nuevas tablas para estos. Sucede que en el punto #1 del código anterior, el compilador aún no ha llenado la tabla con el nuevo char foo (esto se debe a la compilación lineal). Entonces, cuando traduce la primera línea printf , busca en todos los ámbitos activos para encontrar el identificador foo , ve el typedef y lo usa. En el segundo printf , busca en todos los ámbitos activos y encuentra un uso más reciente del identificador foo y lo usa.

over 4 years ago · Santiago Trujillo Denunciar

0

El char foo oculta completamente typedef int foo en su alcance. No puede ver el nombre foo una vez que está oculto. Intente crear un segundo typedef foo foo_t , o cambie el nombre de algo para evitar la "colisión".

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda