1

Xcode iOS プロジェクトを Xcode 3.2.6 から 4.2 に移行しました。wchar_t を非 ASCII 文字のリテラルで初期化しようとすると、警告が表示されます。

wchar_t c1;
if(c1 <= L'я') //That's Cyrillic "ya"

メッセージは次のとおりです。

MyFile.cpp:148:28: 警告: 文字の Unicode エスケープ シーケンスがその型に対して長すぎます [2] MyFile.cpp:148:28: 警告: ワイド文字定数の不要な文字は無視されます [2]

そして、リテラルは期待どおりに機能しません - 比較は失敗します。

-fshort-wchar でコンパイルしています。ソース ファイルは UTF-8 です。Xcode エディターはファイルを正常に表示します。GCC (Xcode 3 を含むいくつかのフレーバー) でコンパイルして動作し、MSVC で動作しました。LLVM コンパイラにこれらのリテラルを認識させる方法はありますか? そうでない場合、Xcode 4 で GCC に戻ることはできますか?

編集:Snow Leopard の Xcode 4.2 - 長い話が理由です。

EDIT2: 真新しいプロジェクトで確認されました。ファイル拡張子は関係ありません - .m ファイルでも同じ動作です。-fshort-wchar も影響しません。これが修正された Xcode のバージョンにアップグレードできるようになるまで、GCC に戻らなければならないようです。

4

3 に答える 3

2

答えではありませんが、うまくいけば役立つ情報です — clang 4.0 (Xcode 4.5.1) で問題を再現できませんでした:

$ uname -a
Darwin air 12.2.0 Darwin Kernel Version 12.2.0: Sat Aug 25 00:48:52 PDT 2012; root:xnu-2050.18.24~1/RELEASE_X86_64 x86_64
$ env | grep LANG
LANG=en_US.UTF-8
$ clang -v
Apple clang version 4.0 (tags/Apple/clang-421.0.60) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin12.2.0
Thread model: posix
$ cat test.c
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    wchar_t c1 = 0;
    printf("sizeof(c1) == %lu\n", sizeof(c1));
    printf("sizeof(L'Я') == %lu\n", sizeof(L'Я'));
    if (c1 < L'Я') {
        printf("Я люблю часы Заря!\n");
    } else {
        printf("Что за....?\n");
    }
    return EXIT_SUCCESS;
}

$ clang -Wall -pedantic ./test.c 
$ ./a.out 
sizeof(c1) == 4
sizeof(L'Я') == 4
Я люблю часы Заря!
$ clang -Wall -pedantic ./test.c -fshort-wchar
$ ./a.out 
sizeof(c1) == 2
sizeof(L'Я') == 2
Я люблю часы Заря!
$ 

同じ動作が clang++ で観察されます (ここでwchar_tは組み込み型です)。

于 2012-10-26T03:44:57.077 に答える
1

実際にソースがUTF-8である場合、これは正しい動作ではありません。ただし、最新バージョンのXcodeでは動作を再現できません。

MyFile.cpp:148:28:警告:文字のUnicodeエスケープシーケンスがタイプに対して長すぎます[2]

このエラーは、「\U001012AB」または「\u0403」のような「ユニバーサル文字名」(UCN)を参照している必要があります。これは、エスケープシーケンスによって表される値が、囲んでいるリテラル型が保持できる値よりも大きいことを示しています。たとえば、コードポイント値が16ビットを超える必要がある場合、16ビットのwchar_tは値を保持できません。

MyFile.cpp:148:28:警告:ワイド文字定数の無関係な文字は無視されます[2]

これは、コンパイラが、ワイド文字リテラル内に複数のコードポイントが表されていると見なしていることを示しています。例L'ab':動作は実装で定義されており、clangとgccはどちらも最後のコードポイント値を使用するだけです。

表示するコードは、少なくともclangでは、これらのいずれかをトリガーするべきではありません。1つ目は、それがUCNにのみ適用されるため、「я」が単一の16ビットwchar_tに簡単に収まるという事実は言うまでもありません。2つ目は、ソースコードエンコーディングが常にUTF-8であると見なされ、「я」のUTF-8マルチバイト表現が単一のコードポイントとして表示されるためです。

ソースが実際にUTF-8であることを再確認して確認することができます。次に、最新バージョンのXcodeを使用していることを確認する必要があります。プロジェクト設定でコンパイラを切り替えてみることもできます>C/ C ++/Objective-C用にコンパイル

于 2012-10-26T04:27:05.433 に答える
1

特定の質問に対する回答はありませんが、llvm-gcc が完全に廃止されたことを指摘したいと思います。Clang と llvm-gcc および gcc の間のデルタを扱った私の経験では、Clang は、その動作が驚くべきものであっても、C++ 仕様に関しては多くの場合正しいものです。

于 2012-10-26T03:36:57.653 に答える