que - sizeof c++
¿Por qué ''auto'' no respeta el operador unario negativo? (4)
El problema real aquí es que el uso del operador unario negativo, al igual que el resto de los operadores aritméticos incorporados, está sujeto a promociones integrales . Así que, sorprendentemente, el resultado de aplicar menos unario a size_t
seguirá siendo size_t
y no hay necesidad de culpar a auto
.
Contra-ejemplo. En este caso, debido a las promociones integrales, el tipo de x
será int
por lo que la salida será -1
:
unsigned short a{1};
auto x{-a};
cout << x << endl;
Soy bastante nuevo en C ++ pero encuentro este comportamiento de auto
raro:
class A{};
int main() {
A a;
auto x = -(sizeof(a));
cout << x << endl;
return 0;
}
La variable x unsigned
está unsigned
en este caso, aunque utilicé el operador unario negativo en la inicialización de la variable. ¿Cómo es que solo se considera el tipo de devolución de sizeof
( std::size_t
) pero no el hecho de que el número almacenado será negativo debido al operador utilizado?
Soy consciente de que size_t
es un int sin firmar.
Lo he intentado con GCC 8.1.0 y C ++ 17.
El resultado de (unario) aplicado a un valor sin signo no está firmado y sizeof
devuelve un valor sin signo.
El operando del operador unario debe tener un tipo de enumeración aritmética o no combinada y el resultado es la negación de su operando. La promoción integral se realiza en operandos integrales o de enumeración. El valor negativo de una cantidad sin signo se calcula restando su valor de 2 ^ n, donde n es el número de bits en el operando promocionado. El tipo de resultado es el tipo del operando promocionado.
El resultado de
sizeof
ysizeof...
es una constante de tipostd::size_t
Para evitar el comportamiento definido de implementación, debe convertir a int
antes de aplicar el -
Si el tipo de destino está firmado, el valor no cambia si puede representarse en el tipo de destino; de lo contrario, el valor está definido por la implementación.
class A{};
int main() {
A a;
auto x = -(int{sizeof(a)});
cout << x << endl;
return 0;
}
Si echamos un vistazo a: https://en.cppreference.com/w/cpp/language/sizeof , el resultado es de tipo size_t
que unsigned
está unsigned
. Debes declararlo explícitamente como signed int
para permitir valores negativos.
En lugar de auto
puedes escribir int
que permite valores negativos.
Su expresión -(sizeof(a))
aplica el operador unario a un valor de tipo sin signo. El operador unario no convierte un valor integral sin signo en uno firmado; más bien define qué valor sin signo será el resultado de una operación como la siguiente (ver operadores aritméticos unarios en cppreference.com ):
El operador unario negativo incorporado calcula el negativo de su operando promocionado. Para unsigned a, el valor de -a es 2 ^ b -a, donde b es el número de bits después de la promoción.
Por lo tanto, incluso si puede ser sorprendente, el auto
funciona correctamente, ya que el resultado de aplicar el operador unario a un valor sin signo sigue siendo un valor sin signo.