Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: варнинг в ewarm520
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
wangan
код:
unsigned char gg;
gg = ~0x76;
gg = ~0x86;

в третей строке компиллер выдает Warning[Pe069]: integer conversion resulted in truncation
непонеме? и как выйти из положения кроме как отключить этот варнинг и вообще какова причина?
ps. инвертирует верно
KRS
Цитата(wangan @ Sep 19 2008, 09:03) *
в третей строке компиллер выдает Warning[Pe069]: integer conversion resulted in truncation

потому что константа 0x86 (по умолчанию целое со знаком) а т.к. приводится к беззнакому байту получается варнинг.
Хотя странно обычно такие варнинги при константах 0x80000000;
в общем надо или забить или U поставить.
Сергей Борщ
Цитата(KRS @ Sep 19 2008, 09:46) *
потому что константа 0x86 (по умолчанию целое со знаком) а т.к. приводится к беззнакому байту получается варнинг.
Вот я тоже примерно так хотел ответить, но есть нестыковки. Константа, объявленная без модификаторов (U, L, LL ULL) имеет тип signed int. При этом не происходит приведений типа к int и расширений знака. Что 0x76, что 0x86 должны после операции ~ иметь взведенные старшие биты. Т.е. ругань должна быть и на вторую строку тоже. Если безумно предположить, что константы 0x76 и 0x86 имеют тип signed char, то перед операцией ~ они, в соответствии с integer promotions rules должны быть приведены к типу int и вот тут у числа 0x86 будет расширен знак, что после операции ~ даст сброшенные старшие биты у ~0x86 и взведенные у 0x76. Т.е. в этом случае наоборот, ругань должна быть на вторую строчку, а не на первую.
В общем "нутром чую, что пол-литра, а объяснить не могу"

Цитата(KRS @ Sep 19 2008, 09:46) *
в общем надо или забить
В корне неверно. Когда таких "забитых" накопится больше трех, в них обязательно потеряется что-нибудь действительно опасное. Поэтому лучше все же победить причину. На совсем крайний случай есть #pragma diag_suppres и обратная ей, которыми можно обрамить неприятную строчку, но я вам этого не говорил wink.gif

P.S. GCC ругается так же.

Вот загадка:
Код
uint8_t i;
int i2;
void test()
{
    i = ~ 0x76;
    i2 = ~ 0x76;
}
// ругани нет
325 0000 89E8              ldi r24,lo8(-119)    ;  tmp51,
326 0002 8093 0000         sts i,r24    ;  i, tmp51
327                   .LSM43:
328 0006 89E8              ldi r24,lo8(-119)    ;  tmp52,
329 0008 9FEF              ldi r25,hi8(-119)    ;  tmp52,
330 000a 9093 0000         sts (i2)+1,r25    ;  i2, tmp52
331 000e 8093 0000         sts i2,r24    ;  i2, tmp52

uint8_t i;
int i2;
void test()
{
    i = ~ 0x86;
    i2 = ~ 0x86;
}
// ругань есть
325 0000 89E7              ldi r24,lo8(121)    ;  tmp51,
326 0002 8093 0000         sts i,r24    ;  i, tmp51
327                   .LSM43:
328 0006 89E7              ldi r24,lo8(-135)    ;  tmp52,
329 0008 9FEF              ldi r25,hi8(-135)    ;  tmp52,
330 000a 9093 0000         sts (i2)+1,r25    ;  i2, tmp52
331 000e 8093 0000         sts i2,r24    ;  i2, tmp52
Я пас. Но я в тупике от того, что нету ругани в первом случае.
KRS
Цитата(Сергей Борщ @ Sep 19 2008, 12:22) *
Т.е. ругань должна быть и на вторую строку тоже

Не должна - потому что ругань именно на преобразование константы! А операция ~ уже происходит над преобразованной к unsigend char и получается unsigned char!
Сергей Борщ
Цитата(KRS @ Sep 19 2008, 13:23) *
Не должна - потому что ругань именно на преобразование константы! А операция ~ уже происходит над преобразованной к unsigend char и получается unsigned char!
Константа и так имеет тип int и никакого преобразования с ней не происходит. Согласно integer promotion rules операнд ~ должен быть преобразован к int если его размер меньше int. В этом можно убедиться, явно задав константе тип (0x86U). Ругань должна быть именно на преобразование результата ~ к unsigned char.
Цитата
48) The integer promotions are applied only: as part of the usual arithmetic conversions, to certain argument expressions, to the operands of the unary +, -, and ~ operators, and to both operands of the shift operators, as specified by their respective subclauses.
KRS
Цитата(Сергей Борщ @ Sep 19 2008, 15:06) *
Константа и так имеет тип int и никакого преобразования с ней не происходит. В этом можно убедиться, явно задав константе тип (0x86U). Ругань должна быть именно на преобразование результата ~ к unsigned char.

хотя точно там же нет других операндов в выражении. поэтому по правилам С все считается в типе int.

у меня компилер выдал warning и на такую конструкцию
gg = ~((unsigned char)0x86);
что вообще странно, потому что операция ~ по стандарту не меняет тип! т.е. взяли unsigned char - получили unsigned char! откуда варнинг непонятно!
Сергей Борщ
Цитата(KRS @ Sep 19 2008, 14:20) *
потому что операция ~ по стандарту не меняет тип!
Меняет. Я специально привел цитату из стандарта.
KRS
Цитата(KRS @ Sep 19 2008, 15:20) *
хотя точно там же нет других операндов в выражении. поэтому по правилам С все считается в типе int.

у меня компилер выдал warning и на такую конструкцию
gg = ~((unsigned char)0x86);
что вообще странно, потому что операция ~ по стандарту не меняет тип! т.е. взяли unsigned char - получили unsigned char! откуда варнинг непонятно!


Да получастея что в С99 уже меняет! на int. ( из -за integer promotion)
Сергей Борщ
Цитата(KRS @ Sep 19 2008, 14:20) *
у меня компилер выдал warning и на такую конструкцию
gg = ~((unsigned char)0x86);
У меня выругался и на gg = 0xFF89;//~0x76 и на gg = 0xFF79; //~0x86, что логично. Но по приведенным выше листингам он именно эти значения и получал после ~, при этом ругаясь только на одно из них.

"Съехала, не жди. Твоя крыша". Я пас:
Код
void test()
{
    uint8_t i;
    i = (int)0xFF79; //~ 0x86;  - ругается
    i = (int)0xFF89; //~ 0x76;  - не ругается.
Если только предположить, что он сначала делает приведение int->signed char, в этом месте из-за отбрасывания старших разрядов число превращается из отрицательного в положительное, на что и идет ругань, а уже после этого идет преобразование signed char->unsigned char. На этом мои версии закончились.
KRS
Цитата(Сергей Борщ @ Sep 19 2008, 15:39) *
Код
void test()
{
    uint8_t i;
    i = (int)0xFF79; //~ 0x86;  - ругается
    i = (int)0xFF89; //~ 0x76;  - не ругается.

а это уже вообще интересно! похоже ругается именно на старший бит в байте.
но я на 5.20 проверил у меня на обе строчки ругается. А у вас какая версия?

Причем стоит заметить что здесь везде упоминался
Warning[Pe069]: integer conversion resulted in truncation

А не
Warning[Pe068]: integer conversion resulted in a change of sign
который как раз и появляется например здесь int i = 0x80000000 + 1;
Сергей Борщ
Цитата(KRS @ Sep 19 2008, 14:55) *
а это уже вообще интересно! похоже ругается именно на старший бит в байте.
но я на 5.20 проверил у меня на обе строчки ругается. А у вас какая версия?
avr-gcc 4.1.2. Сообщение выглядит так: warning: large integer implicitly truncated to unsigned type
wangan
во а вот так вроде нормально:

unsigned char gg;
gg = ~0x76;
gg = (unsigned char)~0x86;
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.