none
Язык C, тип char RRS feed

  • Вопрос

  • Здравствуйте, у меня вопрос относительно типа char.

    Согласно Стандарту, тип char может быть как signed, так и unsigned.
    Так же из Стандарта известно, что переполнение знакового целого - это неопределенное поведение

    Понятно, что знаковые целые на большинстве платформ представлены в виде дополнительного кода, поэтому переполнение таких знаковых целых к неопределенному поведению не приведет, но...

    Как быть-то с этим двуликим char?
    Практически все стандартные функции (printf(), strcmp() и пр.) работают с char, и попытка скормить этим функциям signed/unsigned практически всегда приводит к предупреждениям, которые зависят от компилятора/платформы.

    Плюс, очень серьезная проблема заключается в том, что, например, выражение if (a > b) может вести себя совсем не так, как ожидается:

    char a = -1; char b = 130; if (a > b) { // Если char = unsigned char, то a = 255 окажется больше b = 130.

    // Если char = signed char, то a = -1 окажется меньше b = 130.

    // Особо неприятная ситуация, если a и b будут signed-unsigned или наоборот.

    }

    Хотелось бы быть уверенным в том, что делает char c = -1; но такой уверенности у меня больше нет.

    К тому же люди, более или менее знающие Стандарт, говорят о том, что указатель (unsigned char*) не может быть неявно приведен к указателю (char*).

    Что же со всем этим делать при таком количестве неоднозначностей?
















    • Изменено MGNeo 20 апреля 2018 г. 6:41
    20 апреля 2018 г. 5:30

Ответы

  • "Как быть-то с этим двуликим char?"

    Не использовать его в тех ситуациях, где знаковость имеет значения (т.е., видимо, в любых арифметических операциях).

    Тип char существует с одной целью - представлять символ как элемент строки, независимо от его внутренней реализации, поэтому библиотечные функции работы со строками и просят именно его. Если нужно оперировать кодом символа как числом, следует преобразовать его в unsigned char, и работать уже с ним. Преобразование в беззнаковый тип гарантированно работает, так что это не проблема. Работа с signed char и отрицательными кодами символов - скорее всего плохая идея, если вы пишете код, которые будет компилироваться для разных архитектур.

    • Помечено в качестве ответа MGNeo 20 апреля 2018 г. 7:38
    20 апреля 2018 г. 7:04

Все ответы

  • "Как быть-то с этим двуликим char?"

    Не использовать его в тех ситуациях, где знаковость имеет значения (т.е., видимо, в любых арифметических операциях).

    Тип char существует с одной целью - представлять символ как элемент строки, независимо от его внутренней реализации, поэтому библиотечные функции работы со строками и просят именно его. Если нужно оперировать кодом символа как числом, следует преобразовать его в unsigned char, и работать уже с ним. Преобразование в беззнаковый тип гарантированно работает, так что это не проблема. Работа с signed char и отрицательными кодами символов - скорее всего плохая идея, если вы пишете код, которые будет компилироваться для разных архитектур.

    • Помечено в качестве ответа MGNeo 20 апреля 2018 г. 7:38
    20 апреля 2018 г. 7:04
  • И, дополнительно, не использовать его и для представления символов. Для этого есть WCHAR.

    This posting is provided "AS IS" with no warranties, and confers no rights.

    20 апреля 2018 г. 15:50
    Модератор
  • Точно. Современные компиляторы позволяют даже с  файлами ANSI/UTF8 работать, не прикасаясь к типу char, с использованием дополнительных параметров функции fopen. Разве что если нужно в памяти вручную что-то делать с этими кодировками, только тогда без него не обойтись.

    20 апреля 2018 г. 18:08