Делать size_t и wchar_t переносимыми? - PullRequest
6 голосов
/ 07 октября 2010

Насколько я понимаю, представление size_t и wchar_t полностью зависит от платформы / компилятора.Например, я читал, что wchar_t в Linux сейчас обычно 32-битный, а в Windows - 16-битныйМожно ли как-нибудь стандартизировать их для заданного размера (int, long и т. Д.) В моем собственном коде, сохраняя при этом обратную сопоставимость с существующими стандартными библиотеками C и функциями на обеих платформах?

MyЦель состоит в том, чтобы сделать что-то вроде typedef, чтобы они имели заданный размер.Это возможно, не ломая что-то?Должен ли я сделать это?Есть ли лучший способ?

ОБНОВЛЕНИЕ: Причина, по которой я хотел бы сделать это, заключается в том, чтобы мое кодирование строк было одинаковым как в Windows, так и в Linux

Спасибо!

Ответы [ 5 ]

6 голосов
/ 07 октября 2010

Похоже, вы ищете заголовки C99 и C ++ 0x <stdint.h> / <cstdint>. Это определяет типы как uint8_t и int64_t.

Вы можете использовать Boost's cstdint.hpp, если у вас нет этих заголовков.

5 голосов
/ 07 октября 2010

Вы не хотите переопределять эти типы. Вместо этого вы можете использовать typedefs, такие как int32_t или int16_t (32-разрядные и 16-разрядные со знаком), которые являются частью <stdint.h> в стандартной библиотеке языка C.

Если вы используете C ++, C ++ 0x добавит char16_t и char32_t, которые являются новыми типами (не просто typedef для целочисленных типов), предназначенными для UTF-16 и UTF-32.

Для wchar_t альтернативой является использование библиотеки вроде ICU , которая реализует Unicode независимо от платформы. Затем вы можете просто использовать тип UChar, который всегда будет UTF-16; Вы все еще должны быть осторожны с порядком байтов. ICU также предоставляет преобразователи в и из UChar (UTF-16).

2 голосов
/ 07 октября 2010

Нет. Основная проблема, связанная с попыткой использовать typedef для «исправления» символьного типа, заключается в том, что в результате получается то, что на некоторых платформах соответствует встроенным функциям и литералам широких символов, а на других платформах - нет.

Если вы хотите, чтобы формат строки был одинаковым на всех платформах, вы можете просто выбрать размер и подпись. Вы хотите беззнаковые 8-битные "символы" или 64-битные "символы" со знаком? Вы можете иметь их на любой платформе, которая имеет целочисленный тип соответствующего размера (не все делают). Но они не совсем символы в том, что касается языка, поэтому не ожидайте, что они смогут вызывать strlen или wcslen для них или иметь хороший синтаксис для литералов. Строковый литерал (ну, конвертируется в) char*, а не signed char* или unsigned char*. Широкий строковый литерал представляет собой wchar_t*, что эквивалентно некоторому другому целочисленному типу, но не обязательно тому, который вам нужен.

Итак, вам нужно выбрать кодировку, использовать ее для внутреннего использования, определить свои собственные версии нужных вам строковых функций, реализовать их, а затем преобразовать в / из кодировки платформы по мере необходимости для нестроковых функций, которые принимают строки. utf-8 - достойный вариант, потому что большинство строковых функций Си все еще «работают» в том смысле, что они делают что-то довольно полезное, даже если это не совсем правильно.

0 голосов
/ 07 октября 2010

Просто работайте с UTF-8 внутри страны и преобразуйте в UTF-16 точно в срок, когда передаете аргументы функциям Windows, которые в этом нуждаются. UTF-32, вероятно, никогда не нужен. Поскольку обычно неправильно (в смысле Unicode) обрабатывать отдельные символы вместо строк, работать с заглавными или нормализованными строками UTF-8 не сложнее, чем с UTF-32.

0 голосов
/ 07 октября 2010

wchar_t будет более липкой калиткой, возможно, чем size_t. Можно принять максимальный размер для size_t (скажем, 8 байт) и привести все переменные к нему перед записью в файл (или сокет). Еще одна вещь, которую нужно иметь в виду, это то, что у вас возникнут проблемы с порядком байтов, если вы попытаетесь написать / прочитать какое-то двоичное представление. В любом случае, wchar_t может представлять кодировку utf-32 в одной системе (я полагаю, что Linux делает это) и может представлять кодировку UTF-16 в другой системе (Windows делает это). Если вы пытаетесь создать стандартный формат между платформами, вам придется решить все эти проблемы.

...