из C стандарта (5.2.1 наборов символов)
... Байт со всеми битами, установленными в 0 , называемый нулевым символом, должен существовать в базовом наборе символов выполнения c; он используется для завершения строки символов .
и (6.4.5 строковых литералов)
6 На этапе перевода 7, байт или код нулевого значения добавляется к каждой многобайтовой символьной последовательности, являющейся результатом строкового литерала или литералов.78) Затем многобайтовая символьная последовательность используется для инициализации массива stati c длительности и длины хранения, которых достаточно содержать последовательность.
Таким образом, каждый строковый литерал сохраняется в виде массива символов со стати c длительности хранения, включая завершающий ноль.
Пустой строковый литерал ""
хранится как
char empty_literal[] = { '\0' };
и имеет тип char[1]
. Следовательно, оператор sizeof для этого литерала (массива символов) выдаст значение 1
типа size_t
, являющегося целым типом без знака.
Когда двоичная операция оценивается, компилятор сначала определяет их общие тип. Например, в условии оператора if
if(1 > -2) printf("Yes");
используется реляционный оператор>. Согласно стандарту C (6.5.8 Реляционные операторы)
3 Если оба операнда имеют тип арифмети c, то выполняются обычные арифметические преобразования.
Так как в условии оба операнда 1
и -2
имеют тип int
, то общий тип операндов целочисленный, и, естественно, 1 больше -2.
В условии В этом операторе if
if( sizeof("") > -2) printf("Yes");
первый операнд имеет тип size_t
, в то время как второй операнд имеет тип int. Ранг типа size_t больше, чем ранг типа int, поэтому второй операнд преобразуется в тип size_t путем распространения знакового бита, а результирующее представление рассматривается как представление значения без знака.
Четный если тип size_t
имеет тот же ранг преобразования, что и тип int
, тем не менее согласно правилам обычного преобразования арифмети c объект со знаком типа int
был преобразован в тип unsigned int
.
Из C стандарта (6.3.1.8 Обычная арифметика c преобразования)
В противном случае, если операнд с целочисленным типом без знака имеет ранг, больший или равный рангу тип другого операнда, а затем операнд с целым типом со знаком преобразуется в тип операнда с целым типом без знака.
Вот демонстрационная программа
#include <stdio.h>
int main(void)
{
unsigned int x = 0;
signed int y = -1;
printf( "x + y > 0 is %s\n", x + y > 0 ? "true" : "false" );
return 0;
}
Ее вывод
x + y > 0 is true