|
варнинг в ewarm520, на gg = ~0x86; |
|
|
|
 |
Ответов
|
Sep 19 2008, 08:22
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(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 и обратная ей, которыми можно обрамить неприятную строчку, но я вам этого не говорил  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 Я пас. Но я в тупике от того, что нету ругани в первом случае.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 19 2008, 11:06
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(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.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 19 2008, 11:20
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555

|
Цитата(Сергей Борщ @ Sep 19 2008, 15:06)  Константа и так имеет тип int и никакого преобразования с ней не происходит. В этом можно убедиться, явно задав константе тип (0x86U). Ругань должна быть именно на преобразование результата ~ к unsigned char. хотя точно там же нет других операндов в выражении. поэтому по правилам С все считается в типе int. у меня компилер выдал warning и на такую конструкцию gg = ~((unsigned char)0x86); что вообще странно, потому что операция ~ по стандарту не меняет тип! т.е. взяли unsigned char - получили unsigned char! откуда варнинг непонятно!
|
|
|
|
|
Sep 19 2008, 11:39
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(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. На этом мои версии закончились.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 19 2008, 11:55
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555

|
Цитата(Сергей Борщ @ 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, 12:05
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|