In C11,
char foo(char x, char y) {
return x % y;
}
Выполняется ли где-нибудь неявное преобразование (например, повышение до int)?
In C11,
char foo(char x, char y) {
return x % y;
}
Выполняется ли где-нибудь неявное преобразование (например, повышение до int)?
Обычные арифметические преобразования применяются к операндам %
так же, как они применяются к операндам других мультипликативных и аддитивных операторов (см. 6.5.5 Мультипликативные операторы).
Операнды повышаются либо до int
, либо до unsigned int
, в зависимости от диапазона типа char
на вашей платформе (см. 6.3.1.8 Обычные арифметические преобразования и 6.3.1.1 Булевы значения, символы и целые числа)
На большинстве реальных платформ операнды будут повышены до int
, поскольку диапазон int
обычно покрывает полный диапазон char
. На более или менее экзотических платформах, где sizeof(char) == sizeof(int)
и char
являются беззнаковыми типами (подразумевая, что диапазон char
не вписывается в диапазон int
), они будут повышены до unsigned int
.
sizeof(char) = 1
в любой реализации.
- person alinsoar; 28.06.2017
sizeof(char) == sizeof(int) == 1
. В этом нет ничего плохого.
- person AnT; 28.06.2017
char
. Если минимальная адресуемая единица памяти вашей машины имеет 16 бит, это будет означать, что следующий больший тип будет иметь по крайней мере 32 бита. Единственный способ иметь 20-битный int
на такой машине — это зарезервировать для него два байта (32 бита, sizeof(int) == 2
), а затем зарезервировать 12 бит в качестве неиспользуемых битов заполнения.
- person AnT; 28.06.2017
the padding
пространство может генерировать представления-ловушки, поэтому интерпретатор иногда должен учитывать заполнение.
- person alinsoar; 28.06.2017
Требование к операндам оператора %
n1570-§6.5.5(p2):
Операнды оператора
%
должны иметь целочисленный тип
В этом случае обычное арифметическое преобразование будет иметь место для обоих операндов, поскольку char
повышается до unsigned int
.
unsigned int
. Размер и подпись char
имеют значение.
- person user694733; 28.06.2017
char is promoted to int Or unsigned int
-- действительно, это очень тонко.
- person alinsoar; 28.06.2017
Да, char обычно повышается до int или unsigned int, но также возможно выполнять вычисления напрямую с chars, если интерпретатор может доказать, что результат будет таким же:
Цитата из Стандарта, 5.1.2.3 Program execution
11 ПРИМЕР 2 При выполнении фрагмента
char c1, c2;
/* ... */
c1 = c1 + c2;
«продвижение целых чисел» требует, чтобы абстрактная машина преобразовывала значение каждой переменной в целочисленный размер, а затем добавляла два целых числа и усекала сумму.
Provided the addition of two chars can be done without §5.1.2.3 Environment 15ISO/IEC 9899:201x Committee Draft — April 12, 2011 N1570 overflow, or with overflow wrapping silently to produce the correct result, the actual execution need only produce the same result, possibly omitting the promotions
.
char
будет всегда преобразовываться в int
или unsigned int
. Это гарантируется C11 6.3.1.1, в котором говорится, что int
имеет более высокий целочисленный ранг преобразования, чем char
. Разница может иметь значение. Рассмотрим char a; _Generic(+a, int: do_something());
. Если char
имеет тот же размер, что и int
, но не преобразовано в int
, то это выражение будет ошибочным, как и для long a
.
- person Lundin; 28.06.2017
int
, полученный неявным продвижением, не используется программой, и где неявное продвижение само по себе не вызывает никаких побочных эффектов, таких как изменение подписи. Например, my_unsigned_char << 31
гарантированно вызовет неопределенное поведение.
- person Lundin; 28.06.2017
....The operands of the % operator shall have integer type.
..so, применяется целочисленное правило продвижения. - person Sourav Ghosh   schedule 28.06.2017sizeof (x % y)
должен дать подсказку. - person Ry-♦   schedule 28.06.2017return (char)((int)x % (int)y);
- person Lundin   schedule 28.06.2017