移植性のない C コードを作成することはまったく問題ありません。これは、そうする多くの正当な理由の 1 つです。システムが ASCII またはそのスーパーセットを使用していると思い込んで、EBCDIC システムでプログラムを実行しようとしないことをユーザーに警告してください。
あなたがとても寛大な気持ちなら、小切手を暗号化することができます。このgperf
プログラムは、このようなチェックを含むコードを生成することが知られています。
_Static_assert('0' == 48, "must be ASCII-compatible");
または、C11 より前のコンパイラの場合は、
extern int must_be_ascii_compatible['0' == 48 ? 1 : -1];
C11 を使用している場合は、文字定数にu
orプレフィックスを使用できますが、プレフィックスは使用できません...U
u8
/* This is useless, doesn't do what you want... */
_Static_assert(0, "this code is broken everywhere");
if (c == '々') ...
/* This works as long as wchar_t is UTF-16 or UTF-32 or UCS-2... */
/* Note: you shouldn't be using wchar_t, though... */
_Static_assert(__STDC_ISO_10646__, "wchar_t must be some form of Unicode");
if (c == L'々') ...
/* This works as long as char16_t is UTF-16 or UCS-2... */
_Static_assert(__STDC_UTF_16__, "char16_t must be UTF-16");
if (c == u'々') ...
/* This works as long as char32_t is UTF-32... */
_Static_assert(__STDC_UTF_32__, "char32_t must be UTF-32");
if (c == U'々') ...
非常に移植性の高い C で書かれ、非 ASCII システムに移植されたプロジェクトがいくつかあります (例)。これにはかなりの量の移植作業が必要であり、コードを EBCDIC システムで実行したいことがわかっていない限り、移植作業を行う本当の理由はありません。
標準について: C 標準を書いている人々は、いくつかのまったく奇妙なものを含め、考えられるすべての C 実装と戦わなければなりません。sizeof(char) == sizeof(long)
、CHAR_BIT != 8
、整数型にトラップ表現があり、sizeof(void *) != sizeof(int *)
、sizeof(void *) != sizeof(void (*)())
、ヒープが割り当てられているなどの既知のシステムがありますva_list
。これは悪夢です。
聞いたこともないシステムで動作するコードを書こうとして自分を打ち負かしたり、C 標準の保証を一生懸命探したりしないでください。
たとえば、C 標準に関する限り、以下は の有効な実装ですmalloc
。
void *malloc(void) { return NULL; }
u8"..."
定数は UTF-8 であることが保証されていますが、エンコーディングが文字あたりそれぞれ 16 ビットと 32 ビットであることを除いて保証はなく、実際のエンコーディングは実装によって文書化されなければならないことに注意してくださいu"..."
。U"..."
要約: 2012 年に ASCII 互換性を想定しても安全です。