Каков тип данных, возвращаемый оператором побитового дополнения?

Я пытаюсь понять, что именно возвращает оператор побитового дополнения в C. (Не в терминах "какое значение", а в терминах "какой тип данных". Полагаю, я понимаю, как теоретически работает бит-дополнение, поэтому нет необходимости переиспользовать это)

Рассмотрим следующий код:

int main(int argc, char **argv){
   char c = 'A';
   printf("%d, %d\n", sizeof(c), sizeof(~c));
   return 0; 
}

В то время как первый sizeof() возвращает 1, последний возвращает 4 на моем компьютере.

Итак, мой вопрос: из какого типа данных является ~ c?

Я работаю над 32-битным Linux, изменится ли результат на 8, если я буду работать на 64-битной машине? До сих пор я догадываюсь, что побитовая операция применяется к регистру, а возвращаемое значение не возвращается к значению char. И может ли это поведение быть другим для других компиляторов, или же стандарт C определяет, что такое возвращено ~ c?

Ответ 1

Оператор ~, перед фактической операцией, выполняет целые акции 1 по типу,
поэтому тип ~c определяется реализацией: 2int или unsigned int.

Также обратите внимание, что результатом sizeof является тип size_t, который должен быть напечатан с помощью %zu not %d.


1 (Цитируется по ISO: IEC 9899: 201x 6.3.1.1 Логические, символы и целые числа 2)
Если int может представлять все значения исходного типа (ограниченные шириной, для бит-поле), значение преобразуется в int; в противном случае он преобразуется в беззнаковое внутр. Они называются целыми акциями. 58) Все остальные типы не изменяются целые рекламные акции. 58) Целые поощрения применяются только: как часть обычных арифметических преобразований, к определенным аргументов выражения, в операнды унарных операторов +, - и ~ и обоих операндов операторов сдвига, как указано в их соответствующих подпунктах.

2 Чтобы выяснить, почему оба типа, а не только int. Это связано с тем, что char может быть либо подписанным, либо без знака, и разрешено стандартом C для unsigned char не быть представленным int, потому что диапазон последнего может быть слишком мал. Если бы вы выбрали тип signed char, его можно было бы повысить до int.

Ответ 2

Из 6.5.3.3, унарные арифметические операторы:

Ограничения:

Операнд унарного оператора + или - должен иметь арифметический тип; оператора ~, целочисленный тип оператора !, скалярного типа.

Семантика:

Результатом оператора ~ является поразрядное дополнение его (продвинутого) операнда (то есть каждый бит в результате устанавливается тогда и только тогда, когда соответствующий бит в преобразованном операнде не задан.) Целое число рекламные акции выполняются в операнде, а результат имеет продвинутый тип.

Подводя итог: операнд ~ имеет целочисленный тип, значение операнда продвигается в соответствии с целыми рекламными акциями, а тип результата выражения - это продвинутый тип. (Целочисленные акции превращают что-либо "меньше", чем int в int или unsigned int, и оставляют все остальное как есть.)