array c sizeof unary-operator

array - ¿C maneja correctamente sizeof(...) y sizeof... en este caso?



sizeof string (3)

En ambos casos, el último rofl es el nombre de la variable. Un nombre de variable está en el alcance tan pronto como aparece; y para el resto del alcance actual, ese identificador en un contexto ordinario (*) siempre significa el nombre de la variable.

El operador sizeof no introduce ningún caso especial para buscar nombres. De hecho, no hay construcciones de lenguaje que usen el significado oculto de un identificador.

En la práctica, es una buena idea no usar el mismo identificador para un tipo y un nombre de variable.

(*) Hay tres contextos especiales para identificadores: nombres de etiquetas, etiquetas de estructura y miembros de estructura. Pero en todos los demás contextos, todos los identificadores comparten un espacio de nombre común: no hay espacios de nombres de identificadores distintos para los nombres de los tipos frente a los nombres de las variables en comparación con los nombres de las funciones, etc.

Aquí hay un ejemplo artificial:

typedef int A; // "A" declared as ordinary identifier, meaning a type name struct A { A A; }; // "A" declared as struct tag and member name -- OK as these are three different name spaces. Member type is "int" A main() // int main() - ordinary context { struct A A(); // "A" declared as ordinary identifier, meaning a function name; hides line 1''s A // A C; // Would be error: ordinary A is a function now, not a typedef for int struct A B; // OK, struct tags have separate name space A:+A().A; // OK, labels and struct members have separate name space, calls function goto A; // OK, label name space }

En el siguiente código, ¿son equivalentes las funciones test y test2 ?

typedef int rofl; void test(void) { rofl * rofl = malloc(sizeof(rofl)); // Is the final rofl here the TYPE? } void test2(void) { rofl * rofl = malloc(sizeof *rofl); // Is the final rofl here the VARIABLE? }

En otras palabras:

  1. ¿El rofl en sizeof(rofl) elige correctamente el tipo de rofl debido a los paréntesis?
  2. ¿El rofl en sizeof *rofl elige correctamente la variable rofl debido a la falta de paréntesis?

Nota: Este es un ejemplo tonto, pero en la práctica puede ocurrir que tengas un nombre de tipo que sea igual al nombre de una variable. De ahí la pregunta.


En esta declaración

rofl * rofl = malloc(sizeof(rofl)); // Is the final rofl here the TYPE?

el nombre de la variable rofl oculta el tipodef nombre rofl . Por lo tanto, en el operador sizeof se usa el puntero rofl que es la expresión tiene el tipo int * .

Lo mismo es válido para esta declaración

rofl * rofl = malloc(sizeof *rofl);

excepto que se usa una expresión con el puntero desreferenciado rofl que tiene el tipo del tipodef nombre rofl que es el tipo int .

Parece que la confusión surge debido a esta definición de gramática C

sizeof unary-expression sizeof ( type-name )

Sin embargo unary-expression puede ser una expresión primaria que es una expresión encerrada entre paréntesis.

Del estándar C (6.5.1 expresiones primarias)

primary-expression: ( expression ) //...

Entonces, por ejemplo, si x es un nombre de una variable, entonces usted puede escribir

sizeof x

o

sizeof( x )

Para mayor claridad, podría insertar espacios en blanco entre el operador sizeof y la expresión primaria

sizeof ( x ) operator primary expression

Para comparar, considere otro operador unario: el más único. Puedes escribir, por ejemplo

+ x

o

+ ( x )

Ahora simplemente sustituya el más único por otro tamaño de operador unario.

En cuanto a ocultar nombres, el problema se puede resolver para estructuras, uniones y enumeraciones porque sus nombres incluyen palabras clave para etiquetas.

Por ejemplo

typedef struct rofl { int x; } rofl; void test(void) { rofl * rofl = malloc(sizeof( struct rofl)); }

En esta función con el operador sizeof se usa type-name struct rofl .

Mientras está en esta función

typedef struct rofl { int x; } rofl; void test(void) { rofl * rofl = malloc(sizeof( rofl)); }

con el operador sizeof se usa una expresión primaria con la variable rofl , que tiene el tipo struct rofl * .


No hay ninguna "elección" o "elección" involucrada. En ambos casos, el rofl hace referencia en cada sizeof invocación es la variable, no el tipo, debido a las reglas de alcance. La variable se declara en el ámbito interno y, por lo tanto, anula el nombre del tipo. La paréntesis del argumento para el operador sizeof es irrelevante.

La mejor de las suertes.