一重引用符 ‘ で囲まれた文字定数または文字リテラルには、一文字しか書けないと考えている方が少なくないようです。例えば、’abc’のような書き方をすると、コンパイルエラーになるか未定義の動作になると考えているのでしょう。しかし、実際にはそんなことはありません。

あれこれ説明する前に、標準規格から引用したいと思います。まずはC言語からです。JIS X3010:2003によると

6.4.4.4 文字定数
(中略)
補足説明 単純文字定数は, 一重引用符で囲まれた一つ以上の多バイト文字の並びとする(例えば ‘x’)。ワイド文字定数は, 英字 L という接頭語が付いていることを除いて単純文字定数と同一とする。後に詳述する幾つかの例外を除いて, 列の要素はソース文字集合の任意の要素とする。それらは実行文字集合の要素に処理系定義の方法で対応付ける。
(中略)
2文字以上を含む(例えば ‘ab’)又は1バイトの実行文字で表現できない文字若しくは逆斜線表記を含む単純文字定数の値は, 処理系定義とする。単純文字定数が単一の文字又は逆斜線表記を含む場合, その値はその単一の文字又は逆斜線表記の値を持つ char 型のオブジェクトを int 型に変換したときの結果の値とする。
(中略)
2文字以上の多バイト文字を又は実行拡張文字集合で表現できない多バイト文字若しくは逆斜線表記を含むワイド文字定数の値は, 処理系定義とする。

となっています。次はC++です。JIS X3014:2003によると

2.13.2 文字リテラル
(中略)
 文字リテラルは, 1文字又は複数文字を一重引用符でくくる(例えば, ‘x’)。その前に英字 L を置く(例えば, L’x’)こともある。L を置かない通常の文字リテラルは, ナロー文字リテラルとも呼ばれる。1個の《c 文字》をくくった通常の文字リテラルは, char 型をもち, その《c 文字》の実行文字集合での符号数値に等しい値をもつ。2個以上の《c 文字》をくくった通常の文字リテラルを, 多文字リテラル(multicharacter literal)という。多文字リテラルは, int 型をもつ。その値は, 処理系定義とする。
 文字 L で始まる文字リテラル(例えば ‘x’)を, ワイド文字リテラルという。ワイド文字リテラルは, wchar_t 型をもつ。2個以上の《c 文字》をくくったワイド文字リテラルの値は, 処理系定義とする。

とのことです。

表現や個々の用語に違いはありますが、C言語もC++も、一重引用符に囲まれた文字定数(または文字リテラル)に複数の文字が記述されることを前提とした仕様になっており、その値は(未定義ではなく)処理系定義です。つまり、移植性に関する問題はあるものの、一重引用符の中に2文字以上書けるということです。

ところで、上記はC99またはC++03までの話です。C11以降およびC++11以降ではchar16_t型とchar32_t型が導入されました。また、C++20からはchar8_t型も導入されました。これらに対応する文字定数もあり、char16_t型の文字定数にはu、char32_t型の文字定数にはU、そしてchar8_t型の文字定数にはu8をそれぞれ接頭辞として付加します。u’a’、U’a’、u8’a’のようにです。

では、これらcharN_t型の文字定数に複数の文字を書くことはできるのでしょうか? これはC言語とC++で事情が違ってきます。規格からの引用は割愛しますが、C言語ではこれら新しい文字定数にも複数文字を書くことができます。一方でC++では複数の文字を書くことはできません。ここにもC言語とC++の微妙な非互換性があります。