4

このコードは、Xcode の以前のリリースでコンパイルされました。Xcode を更新したところ、コンパイルに失敗しました。私のコードに何か問題があると思います。以下のコードのクエスチョン マークは、ISO-8859-1 (0xF6) に従ってエンコードされた o ウムラウト (ö) です。以前は、これを上位 (または拡張) ASCII と呼んでいました。コンパイルエラーはclangのUTF-8入力エンコーディングへの移行と関係があると思いますか??

$ xcrun -sdk macosx10.8 -run clang -v
Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.2.0

$ cat test.c
#include <stdio.h>
int main( int argc, char** argv )
{
    fprintf( stderr, "?\n" );
    return 0;
}

$ xcrun -sdk macosx10.8 -run clang -o test test.c 
test.c:4:23: warning: illegal character encoding in string literal [-Winvalid-source-encoding]
    fprintf( stderr, "<F6>\n" );
                      ^~~~
1 warning generated.
4

1 に答える 1

8

したがって、最新のXcode(4.6)のclangはUTF-8エンコーディングを受け入れ、上位(または拡張)ASCIIについて文句を言うようです。これは、ISO-8859-1に準拠したユニバーサル文字セット(UCS)コードポイントの上位ASCIIが混合されているためです。ソースは適切なUTF-8エンコーディングになりません。新しいclangにUTF-8が必要であることを確認するためにリリースノートをチェックしていませんが、ソースを変更して、適切なUTF-8でエンコードされた小さなo-umlautを使用し、コンパイルしました。

0xF6または246は、小さなo-umlautのUCSコードポイントです。ただし、UTF-8で適切にエンコードするには、ファイルの1バイトに0xF6を配置するだけでは不十分です。適切なUTF-8エンコーディングは2バイトです:0xC30xB6。以下の詳細を参照してください。したがって、お気に入りの16進エディタを開いて、1つの0xF6文字を2つの文字(0xC3 0xB6)に置き換えます。

これが素晴らしい16進エディタです:Hex Fiend

それで、あなたの問題のキャラクターがo-umlautでない場合はどうなりますか?いくつかの一般的な文字のリストを含めましたが、以下の手順に従って、特定の問題を解決するための他のUTF-8エンコーディングを見つけることができます。

| Char | ISO-8859-1 |   UTF-8   |
| ---- | ---------- | --------- |
|  ©   |    0xA9    | 0xC2 0xA9 |
|  ®   |    0xAE    | 0xC2 0xAE |
|  Ä   |    0xC4    | 0xC3 0x84 |
|  Å   |    0xC5    | 0xC3 0x85 |
|  Æ   |    0xC6    | 0xC3 0x86 |
|  Ç   |    0xC7    | 0xC3 0x87 |
|  É   |    0xC9    | 0xC3 0x89 |
|  Ñ   |    0xD1    | 0xC3 0x91 |
|  Ö   |    0xD6    | 0xC3 0x96 |
|  Ü   |    0xDC    | 0xC3 0x9C |
|  ß   |    0xDF    | 0xC3 0x9F |
|  à   |    0xE0    | 0xC3 0xA0 |
|  á   |    0xE1    | 0xC3 0xA1 |
|  â   |    0xE2    | 0xC3 0xA2 |
|  ä   |    0xE4    | 0xC3 0xA4 |
|  å   |    0xE5    | 0xC3 0xA5 |
|  æ   |    0xE6    | 0xC3 0xA6 |
|  ç   |    0xE7    | 0xC3 0xA7 |
|  è   |    0xE8    | 0xC3 0xA8 |
|  é   |    0xE9    | 0xC3 0xA9 |
|  ê   |    0xEA    | 0xC3 0xAA |
|  ë   |    0xEB    | 0xC3 0xAB |
|  ì   |    0xEC    | 0xC3 0xAC |
|  í   |    0xED    | 0xC3 0xAD |
|  î   |    0xEE    | 0xC3 0xAE |
|  ï   |    0xEF    | 0xC3 0xAF |
|  ñ   |    0xF1    | 0xC3 0xB1 |
|  ò   |    0xF2    | 0xC3 0xB2 |
|  ó   |    0xF3    | 0xC3 0xB3 |
|  ô   |    0xF4    | 0xC3 0xB4 |
|  ö   |    0xF6    | 0xC3 0xB6 |
|  ù   |    0xF9    | 0xC3 0xB9 |
|  ú   |    0xFA    | 0xC3 0xBA |
|  û   |    0xFB    | 0xC3 0xBB |
|  ü   |    0xFC    | 0xC3 0xBC |
|  ÿ   |    0xFF    | 0xC3 0xBF |

UTF-8では、下位ASCII(7ビット文字)のみを1文字としてエンコードできます。http://en.wikipedia.org/wiki/UTF-8を参照してください。

長さが8〜11ビットのコードポイントは、UTF-8で次のようにエンコードされます。

110xxxxx  10xxxxxx

この場合、0xF6の後に、上位2ビットがそれぞれ1と0に設定されていないものが続き、正しくエンコードされません。

UTF-8でのこのUCSコードポイント(246または0xF6)の適切なエンコードは、0xC3 0xB6であり、次のようになります。

11000011  10110110

0xF6をエンコードするということは、下位6ビットを取得して2番目のバイトに接続し、上位2ビットを最初のバイトに追加することを意味するためです。例:

0xF6
11110110
   11    <-SPLIT->  110110
     \                 \
110xxxxx           10xxxxxx

0xF6はわずか8ビットであるため、最初のバイトの最初の3つのxを0に設定できます。

11000011  10110110

または:

0xC3 0xB6

うまくいけば、これはあなたがclangが窒息しているどんなファイルでも適切にエンコードするのを助けることができます。私はオープンソースでこの問題に遭遇したようです。多くの場合、問題のある文字はコメント(作成者の名前)に含まれています。その場合は、好きなように変更できます。ソースコードを変更する余裕がない場合もあります。その場合は、エンコーディングを修正して、メンテナにパッチを送信する必要があります。

于 2013-02-06T18:17:38.583 に答える