Совершенно допустимо писать непортативный код C, и это является одной из многих веских причин для этого. Не стесняйтесь предполагать, что ваша система использует ASCII или какой-либо их надмножество и предупреждает пользователей о том, что они не должны пытаться запускать вашу программу в системе EBCDIC.
Если вы чувствуете себя очень щедрым, вы можете закодировать чек. Известно, что программа gperf
генерирует код, который включает такую проверку.
_Static_assert('0' == 48, "must be ASCII-compatible");
Или, предварительно C11 компиляторы,
extern int must_be_ascii_compatible['0' == 48 ? 1 : -1];
Если вы на C11, вы можете использовать u
или 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 систем (example). Для этого потребовалось нетривиальное количество усилий по переносу, и нет никакой реальной причины для усилий, если вы не знаете, что хотите запустить свой код в системах EBCDIC.
По стандартам: Люди, пишущие стандарт C, должны бороться со всеми возможными реализациями C, включая некоторые совершенно странные. Известны системы, в которых sizeof(char) == sizeof(long)
, , интегральные типы имеют ловушки, sizeof(void *) != sizeof(int *)
, sizeof(void *) != sizeof(void (*)())
, va_list
являются выделенными кучами и т. Д. Это кошмар.
Не бить себя, пытаясь написать код, который будет работать в системах, о которых вы даже не слышали, и не пытайтесь найти гарантии в стандарте C.
Например, насколько стандарт C касается, следующее является допустимым выполнение malloc
:
void *malloc(void) { return NULL; }
Обратите внимание, что в то время как u8"..."
константы гарантированно UTF-8, u"..."
и U"..."
не имеют гарантирует, что кодировка составляет 16 бит и 32 бита на символ соответственно, и фактическая кодировка должна быть документирована реализацией.
Резюме: Безопасно предположить совместимость ASCII в 2012 году
Поскольку это кодировка с переменной шириной, что бы вы могли ее сохранить? – Pubby
@Pubby: можно сохранить его как 32-битный тип, требуя нулевого заполнения. –
@ Пубби или просто сам int literal. Но мы можем гарантировать строки ASCII * с строкой 'u8 '' 'литералы; почему нет способа гарантировать букву символов ASCII? –