Перейти к содержанию
    

Компилятор IAR 8.5 Си не дает ошибку

On 8/7/2023 at 9:57 PM, Arlleex said:

В разных компиляторах по-разному, т.к. implementation defined.

Конкретно "практикой" определить можно, получив значение CHAR_MIN.

А вот GCC не считает его ни знаковым, ни беззнаковым, а считает его вообще каким-то третьим видом)

unsigned char * p_uchar;
signed char * p_schar;
char * p_char;


int main(void)
{
	p_char = p_schar;
	p_char = p_uchar;
}

main.c:16:9: warning: pointer targets in assignment from 'signed char *' to 'char *' differ in signedness [-Wpointer-sign]
   16 |  p_char = p_schar;
      |         ^
main.c:17:9: warning: pointer targets in assignment from 'unsigned char *' to 'char *' differ in signedness [-Wpointer-sign]
   17 |  p_char = p_uchar;
      |         ^

И Visual Studio c ним солидарна

Quote

Error (active)    E0513    a value of type "unsigned char *" cannot be assigned to an entity of type "char *"    
Error (active)    E0513    a value of type "signed char *" cannot be assigned to an entity of type "char *"

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 минуту назад, dimka76 сказал:

А вот GCC не считает его ни знаковым, ни беззнаковым, а считает его вообще каким-то третьим видом)

Это не GCC один такой "правильный", это стандарт так говорит:wink:

char, signed char, unsigned char - три разных типа.

А знаковость char "вылазит" тогда, когда осуществляется неявное преобразование его в более старший тип.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 8/7/2023 at 10:07 PM, Arlleex said:

Это не GCC один такой "правильный", это стандарт так говорит:wink:

Да это понятно, я просто провел натурный эксперимент.

On 8/7/2023 at 10:07 PM, Arlleex said:

А знаковость char "вылазит" тогда, когда осуществляется неявное преобразование его в более старший тип.

ОК, спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 hours ago, Arlleex said:

Например, чтобы быстро приводить код в порядок

Я ведь не просто так спросил. Силюсь понять, _где_ именно нужна знаковость или беззнаковость char? Можно пример?

 

8 hours ago, dimka76 said:

Ну, так какой же по умолчанию char в ANSI C ?

Чаще всего знаковый. У всех компиляторов, с которыми я сталкивался, есть ключ, явно указывающий на то, как трактовать char.

7 hours ago, Arlleex said:

А знаковость char "вылазит" тогда, когда осуществляется неявное преобразование его в более старший тип.

Так для этого и придумали int8 и uint8.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В С знаковость char зависит от реализации. В С++ сhar, signed char и unsigned char -- это три разных типа.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 06.08.2023 в 19:47, Arlleex сказал:
В 06.08.2023 в 18:18, razrab83 сказал:

что ни разу нет? По дефолту, т.е. если ни каких специальных указаний компилятору не давать - char знаковый.

Вы стандарт давно (или вообще хоть раз) открывали?

Arlleex & razrab83 - вы оба и правы и неправы. каким будет char - знаковый или беззнаковый определяет не стандарт, а компилятор. Дайте ключ компилятору --char_is_signed, будет знаковый, дайте ключ компилятору --char_is_unsigned - будет беззнаковый. И это не будет поперёк стандарта. 

 razrab83 - вы наверно свою "интернатуру" проходили в 00-ые и наверно на ПК аля Intel. Так и было, gcc на этой архитектуре по дефолту char как signed char. 

Но это не то чтобы "не все компиялторы так делают", это один и тот же компилятор на разных архитектурах может иметь разный результат. Например 

 

Debian GNU/Linux 9.1 (stretch)

gcc version 6.3.0 20170516 (Debian 6.3.0-18)

Intel(R) Core(TM) i3-4150

libgcc-6-dev: 6.3.0-18

char is signed

 

Тот же компилятор, но на др архитектуре

 

gcc version 6.3.0 20170516 (Raspbian 6.3.0-18+rpi1)

ARMv7 Processor rev 4 (v7l)

libgcc-6-dev: 6.3.0-18+rpi

char is unsigned

 

Что же касается iar-a, см мануал (забавно... столько времени спорят и ни кто даже мануал на компилятор не открыл).

 

Descriptions of compiler options

--char_is_signed
Description
By default, the compiler interprets the plain char type as unsigned. Use this option to
make the compiler interpret the plain char type as signed instead.

 

Поэтому, чтобы ваш код был портируемый, для целочисленных однобайтных используйте явный signed char или unsigned char, а лучше uint8_t & int8_t.

 

В 08.08.2023 в 08:25, dxp сказал:

В С++ сhar, signed char и unsigned char -- это три разных типа.

Может быть и так, но компилятор Iar по дефолту принимает char как unsigned char.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 08.08.2023 в 07:52, tonyk_av сказал:

Силюсь понять, _где_ именно нужна знаковость или беззнаковость char? Можно пример?

for( char i=0; i<150; i++)
{
    //код
}

если char будет знаковый и в теле for нет break/goto/return, то вы ни когда не выйдите из цикла. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, tonyk_av сказал:

Чаще всего знаковый. У всех компиляторов, с которыми я сталкивался, есть ключ, явно указывающий на то, как трактовать char.

А я говорю (со своей колокольни, как человек, на 70% времени работающий в ARM Compiler 6 (clang)): char там - беззнаковый по умолчанию. И дополнительной галкой превращается в знаковый.

Я не проверял лично в разных GCC, но беглым гуглением обнаруживается, что в GCC под x86 он по умолчанию знаковый, а под ARM (кроме под Apple) - беззнаковый.
 

Цитата

Так для этого и придумали int8 и uint8.

Да, для этого. Только бывает, что дан именно голый char и с ним производятся операции. И результат будет зависеть от реализации.
 

2 часа назад, dxp сказал:

В С знаковость char зависит от реализации. В С++ сhar, signed char и unsigned char -- это три разных типа.

В Си это тоже три разных типа, ISO/IEC 9899:201x

Цитата

6.2.5 Types

14 The type char, the signed and unsigned integer types, and the floating types are collectively called the basic types. The basic types are complete object types. Even if the implementation defines two or more basic types to have the same representation, they are nevertheless different types.

 

1 час назад, juvf сказал:

Arlleex & razrab83 - вы оба и правы и неправы. каким будет char - знаковый или беззнаковый определяет не стандарт, а компилятор.

Я ровно так и написал. Обращаясь к razrab83, естественно я намеревался показать, что стандарт никогда не утверждал, что char - знаковый.

Более того, чуть выше я написал в ответе dimka76 про то, чем определяется знаковость char. Так в чем я не прав?:wink:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

23 минуты назад, Arlleex сказал:

В Си это тоже три разных типа, ISO/IEC 9899:201x

Цитата

6.2.5 Types

14 The type char, the signed and unsigned integer types, and the floating types are collectively called the basic types. The basic types are complete object types. Even if the implementation defines two or more basic types to have the same representation, they are nevertheless different types.

Из вашей цитаты это не следует. Тут сказано, что тип char, знаковые и беззнаковые целые типы и типы с плавающей точкой являются основными типами. Никаких заявлений про signed char, unsigned char тут нет. 

А вот следующим пунктом говорится

Цитата

15 The three types char, signed char, and unsigned char are collectively called the character types.
The implementation shall define char to have the same range, representation, and behavior as either
signed char or unsigned char.

Т.е. реализация должна определить тип char того же диапазона, представления и (самое главное) поведения, что либо signed char, либо unsigned char. Т.е. char в С по факту всегда либо знаковый, либо беззнаковый. Некоторые компиляторы (тот же IAR) предоставляют выбор пользователю в этом вопросе.

А вот в С++:

Цитата

6.7.1 Fundamental types

Plain char, signed char, and unsigned char are three distinct types, collectively called narrow character
types.

Т.е. явно и непосредственно сказано, что это три различных типа. По смыслу char нужен для хранения представления символов, а signed char и unsigned char -- это по сути целые малой разрядности. Поэтому для строк и символов рекомендуется использовать char, а для чисел singed char и unsigned char. Имхо, С++ в этом вопросе логичнее, чем С. В С так сложилось исторически, и менять уже, не ломая совместимость, они не могут.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 08.08.2023 в 11:14, dxp сказал:

это три различных типа

Да, это 3 различных типа. см пример dimka76. Но тем не менее компилятор что си, что с++, определяет какой будет char без указания знаковости. Если вам мануал от IAR на компилятор с/с++ - это не показатель, то вот пример... x86, gcc, c++. По умолчанию char знаковый. дополнительные указания компилятору не даю, галки не ставлю. Ещё раз - это компиялтор с++, а не си. 

for(char i = -50; i<50; i++)

;

Код собирается без ошибок и предупреждений и работает как следует. Теперь поправим цыфирьки

for(char i = 0; i<150; i++)

;

Собирается с ворнингом

 warning: comparison is always true due to limited range of data type [-Wtype-limits]
  for(char i = 0; i<150; i++)
                  ~^~~~

программа выполняется и зависает в это цикле for.

а вот такой код

int max = 150;

for(char i = 0; i<max; i++)

;

собирается без предупреждений и зависает в for. и если кто-то написал такое и у него это работало там, где plain char воспринимался как unsigned - то там всё работает. а  пересобери там, где plain char == signed char, молча зависнет. И это всё на компиляторе с++ (на си будет такой же результат.... наверно)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

IAR -- это и С, и С++ компилятор. Режим зависит от параметров запуска. В каком  режиме запустите, такое поведение и будет. И оно по факту разное даже согласно базовым документам (стандартам). Если IAR не соблюдает указанное поведение, то это баг. Давно с ним не работал, ничего сказать не могу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

49 минут назад, dxp сказал:

А вот следующим пунктом говорится

А сноску 45 смотрели на свой цитируемый пункт 15?

Цитата

CHAR_MIN, defined in , will have one of the values 0 or SCHAR_MIN, and this can be used to distinguish the two options. Irrespective of the choice made, char is a separate type from the other two and is not compatible with either


По-моему, все предельно однозначно написано.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, Arlleex сказал:

А я говорю (со своей колокольни, как человек, на 70% времени работающий в ARM Compiler 6 (clang)): char там - беззнаковый по умолчанию. И дополнительной галкой превращается в знаковый.

В IAR насколько помню - аналогично. По крайней мере для Thumb-2. Это логично. Потому как в Thumb-2 - LDRB предпочтительнее LDRSB (в плане оптимальности кода).

1 час назад, Arlleex сказал:

Я не проверял лично в разных GCC, но беглым гуглением обнаруживается, что в GCC под x86 он по умолчанию знаковый, а под ARM (кроме под Apple) - беззнаковый.

Также логично, по той же причине (размеру(цене) команд CBW/CWDE/CWD/CDQ/...).

Изначально архитектура x86 была лучше заточена под работу со знаковыми типами. А вот Thumb-2 - с беззнаковыми (LDRB, LDRH, ...).

 

Имхо: именно в этом причина разницы в дефолтной знаковости char у компиляторов для разных платформ. Даже у одного и того же компилятора (GCC).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Строго говоря, текст сноски противоречит смыслу основного пункта. В сноске сказано, что, типа, char является отдельным типом, но в основном пункте сказано, что его поведение или как у знакового, или как у беззнакового, а если это так, то он сам по себе никаких отдельных свойств не несёт и по сути является псевдонимом signed char или unsigned char. Ну, и странно, что такую важную вещь написали где-то в сноске мелким шрифтом. В С++ это прямо сказано в основном тексте без намёков и экивоков. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 08.08.2023 в 11:46, dxp сказал:

Если IAR не соблюдает указанное поведение, то это баг. Давно с ним не работал, ничего сказать не могу.

а в чем баг? Ну хорошо.... пусть будет баг... открываем любой справочник по С++, например этот и видим

Тип char         Размер в байтах 1         Диапазон -128...127

Тип signed char         Размер в байтах 1         Диапазон -128...127

Тип unsigned char         Размер в байтах 1         Диапазон 0...255

mycpp.ru - это вообще кто? они хоть раз открывали стандарт с++? в печку этот справочник

 

Открываем Полный справочник по C++ (2015) Автор: Герберт Шилдт в первоисточнике 

Type    Typical Size in Bits     Minimal Range 

char    8    −127 to 127

unsigned char    8     0 to 255

signed char    8    −127 to 127

Наверно Герберт Шилдт тоже не читал стандарт С++. :mosking: 

даже достал такой древний букварь по СИ ...... диапазон char от -127 до 128. Немудрено, что многие программисты с/с++ считают, что char по дефолту знаковый. 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...