реклама на сайте
подробности

 
 
> Деление int на size_t
sonycman
сообщение Nov 6 2013, 10:37
Сообщение #1


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Возникла непонятка.
Использую деление переменной типа int на значение, возвращаемое функцией sizeof():

int t;
...
t = t / sizeof(buf);
if (t < 0) ...
else ...

Так вот - знак t может быть различный, но после деления на sizeof() компилятор считает, что знак результата становится положительный и отбрасывает ветку кода для обработки отрицательного значения. Даже функция деления используется беззнаковая.
Если вместо sizeof() подставить константу, то всё начинает работать как положено.

Что я делаю не так, подскажите?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
sonycman
сообщение Nov 9 2013, 19:56
Сообщение #2


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Несколько устав уже от нюансов по поводу интерпретации стандатров различными компиляторами, нашёл всё таки время "добить" код, прогнав его через IAR и Keil.
Результаты не совсем однозначные, но вот они, какие есть.

Исходный код:
Код
    volatile int tbuf[20], result;
    while (1)
    {
        int t = 0;
        for (unsigned char c = 0; c < sizeof(tbuf)/sizeof(int); c++)
        {
            t += tbuf[c];
        }
        
        t /= sizeof(tbuf)/sizeof(int);            //деление INT на SIZE_T, приводящее к "тихой" ошибке
        
        result = t < 0 ? t/5 : t;

    }

Генерируется он на всех трёх компиляторах тихо, без ошибок и предупреждений, хотя несёт в себе ошибку, превращающую INT при делении в беззнаковый тип, отбрасывая таким образом все отрицательные значения.
При этом GCC полностью удаляет из полученного кода часть, которая обрабатывает отрицательный результат. В IAR и Keil она присутствует, хотя выполнена может быть далеко не всегда.

Полученный код на GCC (Atmel Studio 6.1):
CODE

6a: 60 e0 ldi r22, 0x00 ; 0
6c: 70 e0 ldi r23, 0x00 ; 0
6e: 80 e0 ldi r24, 0x00 ; 0
70: 90 e0 ldi r25, 0x00 ; 0
72: fb 01 movw r30, r22
74: ee 0f add r30, r30
76: ff 1f adc r31, r31
78: 21 e0 ldi r18, 0x01 ; 1
7a: 30 e0 ldi r19, 0x00 ; 0
7c: 2c 0f add r18, r28
7e: 3d 1f adc r19, r29
80: e2 0f add r30, r18
82: f3 1f adc r31, r19
84: 20 81 ld r18, Z
86: 31 81 ldd r19, Z+1 ; 0x01
88: 82 0f add r24, r18
8a: 93 1f adc r25, r19
8c: 6f 5f subi r22, 0xFF ; 255
8e: 7f 4f sbci r23, 0xFF ; 255
90: 64 31 cpi r22, 0x14 ; 20
92: 71 05 cpc r23, r1
94: 71 f7 brne .-36 ; 0x72 <main+0x1c>
96: 03 d0 rcall .+6 ; 0x9e <__udivmodhi4>
98: 7a a7 std Y+42, r23 ; 0x2a
9a: 69 a7 std Y+41, r22 ; 0x29
9c: e6 cf rjmp .-52 ; 0x6a <main+0x14>


Код IAR (v6.21):
CODE

\ ??main_1:
\ 00000004 E045 LDI R20, 5
\ 00000006 E050 LDI R21, 0
\ 00000008 .... RCALL ?SS_DIVMOD_L02
\ ??main_2:
\ 0000000A 8308 ST Y, R16
\ 0000000C 8319 STD Y+1, R17
\ ??main_0:
\ 0000000E E000 LDI R16, 0
\ 00000010 E010 LDI R17, 0
\ 00000012 E020 LDI R18, 0
\ ??main_3:
\ 00000014 2FEC MOV R30, R28
\ 00000016 5FEE SUBI R30, 254
\ 00000018 2F32 MOV R19, R18
\ 0000001A 0F33 LSL R19
\ 0000001C 0FE3 ADD R30, R19
\ 0000001E 8140 LD R20, Z
\ 00000020 8151 LDD R21, Z+1
\ 00000022 0F04 ADD R16, R20
\ 00000024 1F15 ADC R17, R21
\ 00000026 9523 INC R18
\ 00000028 3124 CPI R18, 20
\ 0000002A F3A0 BRCS ??main_3
\ 0000002C E144 LDI R20, 20
\ 0000002E E050 LDI R21, 0
\ 00000030 .... RCALL ?SS_DIVMOD_L02
\ 00000032 2311 TST R17
\ 00000034 F33A BRMI ??main_1
\ 00000036 CFE9 RJMP ??main_2

Здесь уже ошибки нет, применяется деление со знаком.
Однако, если скомпилировать не Release код, а Debug, при тех же настройках оптимизации, получается код с беззнаковым делением.
Интересно 05.gif

Кейл (uVision v4.72) тоже применяет деление без знака, как и GCC, хотя мне вначале казалось наоборот. Прошу простить за невнимательность smile3046.gif
Код
00000c  2314              MOVS     r3,#0x14
00000e  466a              MOV      r2,sp                ;33
;;;37             
;;;38             result = t < 0 ? t/5 : t;
000010  2405              MOVS     r4,#5
                  |L1.18|
000012  2100              MOVS     r1,#0                ;30
000014  ea4f0001          MOV.W    r0,r1                ;31
                  |L1.24|
000018  f8525020          LDR      r5,[r2,r0,LSL #2]    ;33
00001c  1c40              ADDS     r0,r0,#1             ;31
00001e  4429              ADD      r1,r1,r5             ;33
000020  2814              CMP      r0,#0x14             ;31
000022  d3f9              BCC      |L1.24|
000024  fbb1f0f3          UDIV     r0,r1,r3             ;36
000028  2800              CMP      r0,#0
00002a  da01              BGE      |L1.48|
00002c  fb90f0f4          SDIV     r0,r0,r4
                  |L1.48|
;;;39    
;;;40         }
000030  9014              STR      r0,[sp,#0x50]
000032  e7ee              B        |L1.18|

Логика несколько неясна, после UDIV проверять значение на отрицательный знак? Это возможно разве?
Но не перестаю восхищаться красивым, мощным, ёмким и компактным кодом Cortex ARM. Он в два раза короче, чем код для AVR! disco.gif
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- sonycman   Деление int на size_t   Nov 6 2013, 10:37
- - Xenia   Цитата(sonycman @ Nov 6 2013, 14:37) int ...   Nov 6 2013, 11:24
|- - sonycman   Цитата(Xenia @ Nov 6 2013, 15:24) Результ...   Nov 6 2013, 13:25
||- - defunct   Цитата(sonycman @ Nov 6 2013, 15:25) Но р...   Dec 24 2013, 17:18
|- - mdmitry   Цитата(Xenia @ Nov 6 2013, 15:24) Результ...   Nov 6 2013, 14:20
|- - Xenia   Цитата(mdmitry @ Nov 6 2013, 18:20) А не ...   Nov 6 2013, 16:43
- - V_G   Если перейдете на С++ (язык с более строгим контро...   Nov 6 2013, 14:00
- - sonycman   Программа и так компилируется в плюсах, какого-то ...   Nov 6 2013, 15:11
|- - zhevak   Цитата(sonycman @ Nov 6 2013, 21:11) Прог...   Nov 6 2013, 16:47
|- - AHTOXA   Цитата(sonycman @ Nov 6 2013, 21:11) Прог...   Nov 6 2013, 16:59
|- - sonycman   Цитата(V_G @ Nov 6 2013, 18:00) Если пере...   Nov 6 2013, 22:38
|- - V_G   Цитата(sonycman @ Nov 7 2013, 08:38) Это ...   Nov 7 2013, 00:44
|- - AHTOXA   Цитата(sonycman @ Nov 7 2013, 04:38) А во...   Nov 7 2013, 03:59
|- - zhevak   ... и еще вот тут есть интересные рассуждения про ...   Nov 7 2013, 06:09
|- - sonycman   Цитата(AHTOXA @ Nov 7 2013, 07:59) Ваш ва...   Nov 7 2013, 08:47
|- - AHTOXA   Цитата(sonycman @ Nov 7 2013, 14:47) Веро...   Nov 7 2013, 09:30
|- - sonycman   Цитата(AHTOXA @ Nov 7 2013, 13:30) 1. siz...   Nov 7 2013, 09:37
|- - AHTOXA   Вот уж не ожидал, что приведённое мной объяснение ...   Nov 7 2013, 11:17
|- - sonycman   Цитата(AHTOXA @ Nov 7 2013, 15:17) Вот уж...   Nov 7 2013, 12:27
|- - AHTOXA   Это не мой стандарт, это стандарт языка Си. И лучш...   Nov 7 2013, 16:33
|- - sonycman   Цитата(AHTOXA @ Nov 7 2013, 20:33) (И пос...   Nov 7 2013, 21:31
|- - AHTOXA   Цитата(sonycman @ Nov 8 2013, 03:31) Оба ...   Nov 8 2013, 04:17
- - sonycman   Прошу прощения, поторопился я вчера с выводами, по...   Nov 8 2013, 10:19
|- - zhevak   Да. Было бы любопытно посмотреть на распечатку асс...   Nov 8 2013, 11:29
|- - sonycman   Цитата(zhevak @ Nov 8 2013, 15:29) Да. Бы...   Nov 8 2013, 12:02
|- - zhevak   Цитата(sonycman @ Nov 8 2013, 18:02) Вы п...   Nov 8 2013, 13:39
- - sonycman   Без проблем, только я сейчас на работе, и смогу до...   Nov 8 2013, 14:13
- - ILYAUL   Коллеги , а давайте в отдельной теме. Эта всё таки...   Nov 8 2013, 14:13
|- - IgorKossak   Цитата(ILYAUL @ Nov 8 2013, 16:13) Коллег...   Nov 8 2013, 18:33
|- - maksimp   Цитата(sonycman @ Nov 9 2013, 22:56) При ...   Nov 28 2013, 20:35
- - Genadi Zawidowski   Ну написано же в стандарте явно про беззнаковость ...   Jan 5 2014, 00:20


Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th July 2025 - 21:02
Рейтинг@Mail.ru


Страница сгенерированна за 0.01434 секунд с 7
ELECTRONIX ©2004-2016