Первоначальный вопрос: «почему?»
Причина в том, что определение буквального символа эволюционировало и изменилось, пытаясь при этом оставаться обратно совместимым с существующим кодом.
В темные дни раннего C вообще не было типов. К тому времени, когда я впервые научился программировать на C, были введены типы, но у функций не было прототипов, чтобы сообщить вызывающей стороне, какие типы аргументов были. Вместо этого было стандартизовано, что все, что передается в качестве параметра, будет либо иметь размер int (включая все указатели), либо быть двойным.
Это означало, что когда вы писали функцию, все параметры, которые не были двойными, сохранялись в стеке как целые числа, независимо от того, как вы их объявляли, а компилятор помещал в функцию код, чтобы обработать это за вас.
Это делало вещи несколько непоследовательными, поэтому, когда K&R писали свою знаменитую книгу, они ввели правило, согласно которому символьный литерал всегда будет преобразован в int в любом выражении, а не только в параметре функции.
Когда комитет ANSI впервые стандартизировал C, они изменили это правило так, чтобы символьный литерал был просто int, поскольку это казалось более простым способом достижения того же результата.
Когда разрабатывался C ++, все функции должны были иметь полные прототипы (это еще не требуется в C, хотя это общепринято как хорошая практика). Из-за этого было решено, что символьный литерал может храниться в char. Преимущество этого в C ++ заключается в том, что функция с параметром char и функция с параметром int имеют разные сигнатуры. Это преимущество отсутствует в C.
Вот почему они разные. Эволюция ...