Флаг компилятора C для игнорирования знака

В настоящее время я имею дело с кодом, приобретенным у стороннего подрядчика. Одна структура имеет поле беззнакового символа, в то время как функция, которой они передают это поле, требует знакового символа. Компилятору это не нравится, так как он считает их несовпадающими типами. Тем не менее, он, по-видимому, компилируется для этого подрядчика. Некоторые гуглы сказали мне, что «[i]t зависит от реализации, может ли объект char содержать отрицательные значения». Может ли компилятор подрядчика игнорировать подписанный/неподписанный тип и относиться к ним одинаково? Или есть флаг компилятора, который будет относиться к ним одинаково?

C не самый сильный мой язык - просто посмотрите на мои теги на моей странице пользователя - так что любая помощь будет очень признательна.


person geowa4    schedule 01.09.2009    source источник
comment
Какой компилятор? Большинство [если не все] компиляторов C позволят вам изменить неявную подпись символа, но это флаг, специфичный для компилятора, поэтому общего ответа нет.   -  person dreamlax    schedule 01.09.2009
comment
этот парень: docs.sun.com/source/806-3567/cc_options.html   -  person geowa4    schedule 01.09.2009
comment
Почему бы вам не привести их к правильному типу по мере необходимости?   -  person Judge Maygarden    schedule 01.09.2009
comment
этот код от подрядчика, который еще не ответил на мои звонки. он должен работать, тем более, что нам дали готовый пакет, который непригоден для использования по другим причинам.   -  person geowa4    schedule 01.09.2009


Ответы (3)


На самом деле char, signed char и unsigned char — это три разных типа. Из стандарта (ISO/IEC 9899:1990):

6.1.2.5 Типы

...

Три типа char, signed char и unsigned char вместе называются символьными типами.

(а в С++, например, вы должны (или, по крайней мере, должны) писать функции переопределения с тремя их вариантами, если у вас есть аргумент char)

Обычный char может рассматриваться компилятором как подписанный или неподписанный, но стандарт говорит (также в 6.1.2.5):

Объект, объявленный как тип char, достаточно велик, чтобы хранить любой член базового набора символов выполнения. Если член требуемого исходного набора символов в 5.2.1 хранится в объекте char, его значение гарантировано будет положительным. Если в объекте char хранятся другие величины, поведение определяется реализацией: значения обрабатываются либо как целые числа со знаком, либо как неотрицательные.

а также

Объект, объявленный как подписанный тип char, занимает тот же объем памяти, что и «обычный» объект char.

Символы, упомянутые в 5.2.1, это A-Z, a-z, 0-9, пробел, табуляция, новая строка и следующие 29 графических символов:

! " # % & ' ( ) * + , - . / :
; < = > ? [ \ ] ^ _ { | } ~ 

Отвечать

Все, что я интерпретирую, в основном означает, что символы ascii со значением менее 128 гарантированно будут положительными. Таким образом, если сохраненные значения всегда меньше 128, это должно быть безопасно (с точки зрения сохранения значений), хотя это и не очень хорошая практика.

person hlovdal    schedule 01.09.2009
comment
этот фрагмент кода имеет дело с изображениями, поэтому я подозреваю, что там хранится больше, чем «A» и «b». - person geowa4; 01.09.2009
comment
проблема была решена. по-видимому, возможные значения были от 0 до 100, и мы получили смешанные версии. Спасибо за помощь. - person geowa4; 08.09.2009

Это зависит от компилятора. Например, в VC++ есть параметр компилятора и соответствующий макрос _CHAR_UNSIGNED, определенный, если этот параметр предписывает использовать по умолчанию беззнаковый символ.

person sharptooth    schedule 01.09.2009
comment
Я подумал, что мы использовали разные компиляторы. это настоящая проблема, потому что установка нового здесь может занять вечность, если не невозможно. - person geowa4; 01.09.2009

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

В качестве альтернативы подрядчик может использовать компилятор или параметры компилятора, которые позволяют ему компилировать, игнорируя ошибки или предупреждения. Вы знаете, какая у него среда компиляции?

В любом случае, это нехорошо C. Если один из типов просто char, он зависит от поведения, определяемого реализацией, и поэтому не является переносимым. Если нет, то это неправильно. Я бы обсудил это с подрядчиком.

person David Thornley    schedule 01.09.2009