10

私が与えた以前の回答では'\u0B95'3バイトが必要であり、複数文字のリテラルであるという事実によって引き起こされる次の警告に応答しました。

warning: multi-character character constant [-Wmultichar]

しかし実際には、私は自分が正しいとは思いませんし、gccもそうではないと思います。標準は次のように述べています。

複数のc-charを含む通常の文字リテラルは、複数文字リテラルです。

c-charの生成規則の1つは、ユニバーサル文字名(つまり\uXXXX、または\UXXXXXXXX)です。\u0B95は単一のc-charであるため、これは複数文字のリテラルではありません。しかし、今では厄介になります。規格には次のようにも書かれています。

単一のc-charを含む通常の文字リテラルのタイプは、実行文字セット内のc-charcharのエンコードの数値に等しい値です。

したがって、私のリテラルには、実行文字セット内の文字のタイプcharと値(または、そのセットに存在しない場合は実装定義の値)があります。char基本文字セットのメンバーを格納するのに十分な大きさであると定義されているだけです(これは実際には標準で定義されていませんが、基本実行文字セットを意味すると思います)。

文字(char)として宣言されたオブジェクトは、実装の基本文字セットのメンバーを格納するのに十分な大きさでなければなりません。

したがって、実行文字セットはacharが保持できるすべての値のスーパーセットであるため、私の文字はに収まらない可能性がありcharます。

では、私にはどのような価値charありますか?これはどこにも定義されていないようです。標準では、char16_tリテラルの場合、値が表現できない場合、プログラムの形式が正しくないとされています。ただし、通常のリテラルについては何も述べていません。

どうしたの?これは標準の混乱ですか、それとも何かが足りませんか?

4

4 に答える 4

1

私は次のように主張します:

文字リテラルの値は、(接頭辞のないリテラルの場合)定義された実装定義の範囲外にある場合、実装定義ですchar...(セクション2.14.3.4から)

実装で定義された範囲( 8ビットの場合)'\u0B95'の範囲外の場合、その値は実装で定義され、その時点でGCCはその値を複数のsのシーケンスにして、複数文字のリテラルになります。charcharc-char

于 2012-11-25T05:16:04.347 に答える
1

誰かが私の質問の 2 番目の部分 (どのような価値がありますか?) に正しく答えた回答を投稿しましたが、charその後投稿を削除しました。その部分は正しかったので、最初の部分 (多文字リテラルですか?) に対する私の回答と共にここに再掲します。


'\u0B95'は複数文字のリテラルではなく、gcc はここで間違っています。質問で述べたように、複数文字リテラルは (§2.14.3/1) で定義されています。

複数のc-charを含む通常の文字リテラルは、複数文字リテラルです。

ユニバーサル文字名はc-charの 1 つの拡張であるため、リテラルには 1 つのc-char'\u0B95'のみが含まれます。通常のリテラルに、6 つの別個の文字 ( 、、など)と見なされるように汎用文字名を含めることができない場合は理にかなっていますが、この制限はどこにも見つかりません。したがって、これは 1 文字であり、リテラルは複数文字リテラルではありません。\u0B95\u0

これをさらに裏付けるために、なぜ複数の文字と見なされるのでしょうか? この時点では、エンコーディングも行っていないため、何バイトかかるかはわかりません。UTF-16 では 2 バイト、UTF-8 では 3 バイト、想像上のエンコーディングでは 1 バイトしか必要としません。

では、文字リテラルにはどのような値がありますか? 最初に、汎用文字名は実行文字セット内の対応するエンコーディングにマッピングされます。マッピングがない場合は、実装定義のエンコーディングがあります (§2.14.3/5):

ユニバーサル文字名は、指定された文字の適切な実行文字セットのエンコーディングに変換されます。そのようなエンコーディングがない場合、universal-character-name は実装定義のエンコーディングに変換されます。

いずれにせよ、charリテラルはエンコーディングの数値と等しい値を取得します (§2.14.3/1):

単一のc-charを含む通常の文字リテラルのtypecharは、実行文字セット内の c-char のエンコーディングの数値に等しい値です。

ここで重要な部分が、このセクションの別の段落に不都合に隠れてしまいました。値を で表すことができない場合charは、実装定義の値を取得します (§2.14.3/4):

char文字リテラルの値は、 (プレフィックスのないリテラルの場合)定義された処理系定義の範囲外にある場合、処理系定義です...

于 2012-11-25T19:42:09.803 に答える