Pierwotne pytanie brzmi „dlaczego?”
Powodem jest to, że definicja znaku dosłownego ewoluowała i zmieniła się, starając się zachować zgodność wsteczną z istniejącym kodem.
W ciemnych dniach wczesnego C nie było żadnych typów. Do czasu, gdy po raz pierwszy nauczyłem się programowania w C, wprowadzono typy, ale funkcje nie miały prototypów, które mogłyby powiedzieć dzwoniącemu, jakie są typy argumentów. Zamiast tego ustandaryzowano, że wszystko przekazywane jako parametr będzie albo wielkością int (obejmującą wszystkie wskaźniki), albo będzie podwójne.
Oznaczało to, że kiedy pisałeś funkcję, wszystkie parametry, które nie były podwójne, były przechowywane na stosie jako wartości typu int, bez względu na to, jak je zadeklarowałeś, a kompilator umieścił kod w funkcji, aby obsłużyć to za Ciebie.
To spowodowało, że rzeczy były nieco niespójne, więc kiedy K&R napisał swoją słynną książkę, przyjęli zasadę, że literał znakowy będzie zawsze promowany do int w dowolnym wyrażeniu, a nie tylko w parametrze funkcji.
Kiedy komisja ANSI po raz pierwszy ustandaryzowała C, zmienili tę zasadę, aby literał znakowy był po prostu int, ponieważ wydawało się to prostszym sposobem osiągnięcia tego samego.
Kiedy projektowano C ++, wszystkie funkcje musiały mieć pełne prototypy (nadal nie jest to wymagane w C, chociaż jest to powszechnie akceptowane jako dobra praktyka). Z tego powodu zdecydowano, że literał znaku może być przechowywany w char. Zaletą tego w C ++ jest to, że funkcja z parametrem char i funkcja z parametrem int mają różne sygnatury. Ta zaleta nie występuje w przypadku C.
Dlatego są różne. Ewolucja...