c++ - smart - Puede sizeof retorno 0(cero)
solidity español (10)
Aquí hay una prueba, donde sizeof rinde 0
#include <stdio.h>
void func(int i)
{
int vla[i];
printf ("%u/n",(unsigned)sizeof vla);
}
int main(void)
{
func(0);
return 0;
}
¿Es posible que el operador sizeof devuelva 0 (cero) en C o C ++? Si es posible, ¿es correcto desde el punto de vista de los estándares?
Cada objeto en C debe tener una dirección única. Dicho de otra manera, una dirección no debe contener más de un objeto de un tipo determinado (para que la desreferenciación del puntero funcione). Dicho esto, considera una estructura ''vacía'':
struct emptyStruct {};
y, más específicamente, una serie de ellos:
struct emptyStruct array[10];
struct emptyStruct* ptr = &array[0];
Si los objetos estaban realmente vacíos (es decir, si sizeof(struct emptyStruct) == 0
), entonces ptr++ ==> (void*)ptr + sizeof(struct emptyStruct) ==> ptr
, lo cual no tiene sentido. ¿A qué objeto *ptr
se referiría, ptr[0]
o ptr[1]
?
Incluso si una estructura no tiene contenido, el compilador debe tratarla como si tuviera un byte de longitud para mantener el principio de "una dirección, un objeto".
La especificación del lenguaje C (sección A7.4.8) expresa este requisito como
cuando se aplica a una estructura o unión, el resultado (del operador
sizeof
) es el número de bytes en el objeto, incluido el relleno requerido para hacer que el objeto se convierta en una matriz
Como un byte de relleno debe agregarse a un objeto "vacío" para que funcione en una matriz, sizeof()
debe devolver un valor de al menos 1 para cualquier entrada válida.
Edición: la sección A8.3 de la especificación de C llama a una estructura sin una lista de miembros un tipo incompleto , y la definición de sizeof
especifica específicamente (con énfasis agregado):
El operador (sizeof) no puede aplicarse a un operando de tipo de función, o de tipo incompleto , o a un campo de bits.
Eso implicaría que usar sizeof
en una estructura vacía sería tan inválido como usarlo en un tipo de datos que no se ha definido. Si su compilador permite el uso de estructuras vacías, tenga en cuenta que el uso de sizeof
en ellas no está permitido según la especificación de C. Si su compilador le permite hacer esto de todos modos, entienda que este es un comportamiento no estándar que no funcionará en todos los compiladores; No confíe en este comportamiento.
Edición: Consulte también esta entrada en las preguntas frecuentes de Bjarne Stroustrup.
Creo que nunca devuelve 0 en c, no se permiten estructuras vacías
En C ++, una clase o estructura vacía tiene un sizeof
al menos 1 por definición. Del estándar de C ++, 9/3 "Clases": "Los objetos completos y los subobjetos de miembros de tipo de clase tendrán un tamaño distinto de cero".
En C no se permite una estructura vacía, excepto por extensión (o un defecto en el compilador).
Esto es una consecuencia de la gramática (que requiere que haya algo entre las llaves) junto con esta oración del 6.7.2.1/7 "Especificadores de estructura y unión": "Si la estructura-declaración-lista no contiene miembros con nombre, el comportamiento es indefinido".
Si se permite una estructura de tamaño cero, entonces es una extensión de lenguaje (o un defecto en el compilador). Por ejemplo, en GCC, la extensión se documenta en "Estructuras sin miembros" , que dice:
GCC permite que una estructura C no tenga miembros:
struct empty { };
La estructura tendrá tamaño cero. En C ++, las estructuras vacías son parte del lenguaje. G ++ trata las estructuras vacías como si tuvieran un solo miembro de tipo
char
.
Si tienes esto:
struct Foo {};
struct Bar { Foo v[]; }
g++ -ansi
devuelve sizeof (Bar) == 0. Al igual que el compilador clang & intel.
Sin embargo, esto no se compila con gcc. Deduzco que es una extensión de C ++.
en mi opinión, es mejor que sizeof devuelva 0 para una estructura de tamaño 0 (en el espíritu de c). pero luego el programador debe tener cuidado cuando toma el tamaño de una estructura vacía.
pero puede causar un problema. cuando se define la matriz de tales estructuras, entonces
& arr [1] == & arr [2] == & arr [0]
Lo que les hace perder sus identidades.
Supongo que esto no responde directamente a tu pregunta, si es posible o no. Bueno eso puede ser posible dependiendo del compilador. (como se dijo en la respuesta de Michael arriba).
sizeof
nunca devuelve 0
en C y en C ++. Cada vez que vea sizeof
evaluando a 0
es un error / fallo / extensión de un compilador específico que no tiene nada que ver con el idioma.
isbadawi vacías, como mentions isbadawi . También gcc permite arreglos de tamaño 0 :
int a[0];
sizeof(a);
EDITAR: Después de ver el enlace de MSDN, probé la estructura vacía en el VS2005 y sizeof devolvió 1. No estoy seguro si es un error de VS o si la especificación es de alguna manera flexible sobre ese tipo de cosas
struct Empty {
} em;
struct Zero {
Empty a[0];
} zr;
printf("em=%d/n", sizeof(em));
printf("zr=%d/n", sizeof(zr));
Resultado:
em=1
zr=0
typedef struct {
int : 0;
} x;
x x1;
x x2;
Bajo MSVC 2010 (/ Za / Wall):
sizeof(x) == 4
&x1 != &x2
Bajo GCC (-ansi -pedantic -Wall):
sizeof(x) == 0
&x1 != &x2
es decir, aunque bajo GCC tiene un tamaño cero, las instancias de la estructura tienen direcciones distintas.
ANSI C (C89 y C99: no he mirado C ++) dice: "Será posible expresar la dirección de cada byte individual de un objeto de forma única". Esto parece ambiguo en el caso de un objeto de tamaño cero, ya que podría decirse que no tiene bytes.
Edición: "Una declaración de campo de bits sin declarador, pero solo dos puntos y un ancho, indica un campo de bits sin nombre. Como caso especial de esto, un campo de bits con un ancho de 0 indica que no hay más campos de bits se debe empaquetar en la unidad en la que se colocó el campo de bits anterior, si lo hubiera, ".