#include <stdio.h>
int main(void)
{
if (sizeof(int) > -1)
printf("True");
else
printf("False");
}
Это печатает False. Почему sizeof() не возвращает значение в if?
#include <stdio.h>
int main(void)
{
if (sizeof(int) > -1)
printf("True");
else
printf("False");
}
Это печатает False. Почему sizeof() не возвращает значение в if?
sizeof не является функцией, это оператор. Скобки не являются частью имени оператора.size_t, что приводит к "обычным арифметическим преобразованиям", в которых -1 преобразуется в unsigned, и в этом случае это очень большое число.В основном вы сравниваете 4 > 0xffffffffu, или что-то близкое к этому, по крайней мере. Подробнее см. этот вопрос.
Неподписанное и подписанное целочисленное продвижение (точнее, "обычные арифметические преобразования" ). sizeof дает значение типа size_t, и по сравнению с беззнаковым значением (которое size_t есть), -1 продвигается к этому типу и переполняется и становится огромным.
Незнакомое целочисленное переполнение имеет четко определенное поведение и должно приниматься как modulo 2 ^ width, где width - это количество бит в конкретном неподписанном целочисленном типе. Итак, если у вас есть 32-разрядная ширина size_t и int, например, ваше сравнение будет эквивалентно с
if (4 > 4294967295u)
что, очевидно, неверно.
sizeof(int) и -1.sizeof(int) имеет тип size_t, который гарантированно является целым числом без знака. На практике size_t, скорее всего, будет как минимум равным unsigned int для любой системы.-1 имеет тип int, что эквивалентно signed int.Это состояние (C11 6.3.1.8):
...
В противном случае, если тип операнда со знаком целочисленного типа может представляют все значения типа операнда без знака целочисленный тип, то операнд с целым числом без знака преобразуется к типу операнда со знаком целочисленного типа.
В противном случае оба операнды преобразуются в целочисленный тип без знака, соответствующий тип операнда со знаком целочисленного типа.
int не может соответствовать всем значениям a size_t.-1 преобразуется в целое число без знака. На практике size_t скорее всего эквивалентен либо unsigned int, либо unsigned long. Что бы ни случилось, когда вы сохраняете -1 в такой переменной, это поведение, определяемое реализацией.0xFFFFFFFF (количество FF зависит от размера int в данной системе).4 > 0xFFFFFFFF оценивается как false.Sizeof - это оператор, который приводит к длинному int без знака. Следовательно, при сравнении unsigned long int с -1, который хранится как 0xffffffff (размер int равен 4 байтам).
-1 по умолчанию является целым знаком. Но, в сравнении между подписанным int и unsigned int, компилятор идет с неявным typecasting подписанного int в unsigned int. Это приводит к тому, что unsigned -1 будет приблизительно равным 4.6giga-значению.
Следовательно, выход false.
Просто проверьте это и убедитесь сами.
#include <stdio.h>
main() {
unsigned int a=4;
int b = -1;
//this is what you're doing
printf("%u vs %u\n", a, (unsigned int)b);
//this is what you want to do instead
printf("%d vs %d\n", (int)a, b);
}