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

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> Деление int на size_t
sonycman
сообщение Nov 7 2013, 09:37
Сообщение #16


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

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



Цитата(AHTOXA @ Nov 7 2013, 13:30) *
1. sizeof() возвращает size_t, независимо от значения.
2. int/size_t возвращает size_t. (при условии sizeof(int) == sizeof(size_t) )
Это требование стандарта.
Вы считаете, что несоблюдение компилятором стандарта языка говорит о том, что этот компилятор "более продвинутый"? sm.gif

Кстати, есть вариант, что в этих продвинутых компиляторах int просто длиннее, чем size_t, и поэтому всё получается нормально без нарушения стандарта.


А что, Вы будете спорить, что IAR и прочие коммерческие компилеры - более продвинутые?
Это видно и на моём примере sm.gif
А в защиту GCC можно сказать только - что он "блюдёт" стандарты. sm.gif
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 7 2013, 11:17
Сообщение #17


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Вот уж не ожидал, что приведённое мной объяснение может вызвать такую реакцию.
Подумайте ещё вот о чём. Существует ненулевая вероятность, что в какой-то из следующих версий IAR данное несоответствие стандарту устранят... sm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 7 2013, 12:27
Сообщение #18


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

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



Цитата(AHTOXA @ Nov 7 2013, 15:17) *
Вот уж не ожидал, что приведённое мной объяснение может вызвать такую реакцию.
Подумайте ещё вот о чём. Существует ненулевая вероятность, что в какой-то из следующих версий IAR данное несоответствие стандарту устранят... sm.gif

Да обычная реакция. Когда в очередной раз слышишь, что маразм из разряда -2/1=2 - это стандарт.

Не только IAR "игнорирует" ваш стандарт, но и CodeVisionAVR.
Я еще Keil не проверял, возможно, он тоже из разряда "недоделанных" sm.gif

Может быть, отличия в результатах компиляции - вовсе не различная трактовка стандартов, а работа оптимизации?
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 7 2013, 16:33
Сообщение #19


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Это не мой стандарт, это стандарт языка Си.
И лучше такой стандарт, чем никакого. Странно, что вы, вроде бы достаточно опытный разработчик, этого не понимаете.
А уж ссылки на CodeVisionAVR - это вообще нонсенс, поскольку давно известно, что CodeVisionAVR - это компилятор "языка, похожего на Си":)
Вы лучше проверьте "взрослые" компиляторы.
(И посмотрите в IAR, чему там равны sizeof(int) и sizeof(size_t), вдруг и IAR соблюдает стандарт).


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 7 2013, 21:31
Сообщение #20


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

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



Цитата(AHTOXA @ Nov 7 2013, 20:33) *
(И посмотрите в IAR, чему там равны sizeof(int) и sizeof(size_t), вдруг и IAR соблюдает стандарт).

Оба равны двум, что неудивительно. Только у одного 2+2 равно 4, а у второго - 5.
Думаете, какой из них больше соблюдает стандарт?

ЗЫ: сейчас докачаю Кейл и проверю там, на АРМ.

ЗЗЫ: Упс, обновил AtmelStudio на последнюю версию 6.1 (стояла 6.0), ничего в тексте не менял, пересобрал проект - появилось знаковое деление и обработка отрицательных значений.
То есть исправили багу и теперь поведение GCC стало аналогичным IAR.
Попробуйте теперь объяснить, как необходимо правильно трактовать разные умные стандарты laughing.gif

Ставить Кейл пока не стану, уверен, что его код будет аналогичен IAR.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 8 2013, 04:17
Сообщение #21


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(sonycman @ Nov 8 2013, 03:31) *
Оба равны двум, что неудивительно.

Да всяко бывает. Бывает 4 (на АРМ-ах). Бывает и 8 (на 64-битных системах). Ещё бывает, что размер int и size_t разный.
Цитата(sonycman @ Nov 8 2013, 03:31) *
Только у одного 2+2 равно 4, а у второго - 5. Думаете, какой из них больше соблюдает стандарт?

Больше соблюдает тот, у которого результат соответствует стандарту. Если по стандарту должно получиться 5, то второй sm.gif
Цитата(sonycman @ Nov 8 2013, 03:31) *
ЗЗЫ: Упс, обновил AtmelStudio на последнюю версию 6.1 (стояла 6.0), ничего в тексте не менял, пересобрал проект - появилось знаковое деление и обработка отрицательных значений.
То есть исправили багу и теперь поведение GCC стало аналогичным IAR.
Попробуйте теперь объяснить, как необходимо правильно трактовать разные умные стандарты laughing.gif

Очень рад за вас sm.gif
Не знаю, почему так. Возможно, здесь константа вычисляется во время компиляции, и поэтому она трактуется как нетипизированная.
Для интереса попробуйте написать функцию, которая возвращает size_t, и поделить int на результат этой функции.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 8 2013, 10:19
Сообщение #22


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

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



Прошу прощения, поторопился я вчера с выводами, поздно было, допустил невнимательность и рано обрадовался sad.gif
Не заметил приведение типов - нет, версия студии 6.1 всё так же остаётся верна стандартам и сама себе - знак так же отбрасывается, как и раньше.

Зато потестил Кейл - как и предполагал, работает по аналогии с IAR - чихает на стандарты, делит со знаком и его дальнейшей обработкой. Наш человек sm.gif

Подставлял в IAR вместо sizeof() переменную с типом size_t - без разницы, никакого превращения Int в беззнаковый тип не происходит, всё работает как и раньше.
Go to the top of the page
 
+Quote Post
zhevak
сообщение Nov 8 2013, 11:29
Сообщение #23


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



Да. Было бы любопытно посмотреть на распечатку ассеблерного кода в том и другом случае.


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 8 2013, 12:02
Сообщение #24


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

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



Цитата(zhevak @ Nov 8 2013, 15:29) *
Да. Было бы любопытно посмотреть на распечатку ассеблерного кода в том и другом случае.

Вы про IAR? Уточните, пожалуйста.
Смогу предоставить ассемлерный листинг только ночью или завтра, к сожалению.
Go to the top of the page
 
+Quote Post
zhevak
сообщение Nov 8 2013, 13:39
Сообщение #25


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



Цитата(sonycman @ Nov 8 2013, 18:02) *
Вы про IAR? Уточните, пожалуйста.
Смогу предоставить ассемлерный листинг только ночью или завтра, к сожалению.

Честно говоря, я не думал про какой-то конкретный компилятор.
Я под Линем сижу, могу притащить сюда листин от gcc. (Если кто-нибудь меня не опередит к этому времени, гы-гы!)

Давайте какой-нибудь простенький код обуликуем, откомпилируем и сравним. Внимание нужно будет уделить именно арифметическим командам проца, которые как раз занимаются вычислением деления int на size_t.

Ну что, попробуем сделать?


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 8 2013, 14:13
Сообщение #26


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

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



Без проблем, только я сейчас на работе, и смогу добраться до компа только к ночи, и то не надолго.
Думаете, стоит расмотреть только деление, или пройтись по остальным операциям?
Хотя разницы не будет, вероятнее всего.

Постараюсь привести пример с делением и его код из под трех компиляторов - GCC, IAR и Keil. Последний под ARM.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Nov 8 2013, 14:13
Сообщение #27


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Коллеги , а давайте в отдельной теме. Эта всё таки про студию


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Nov 8 2013, 18:33
Сообщение #28


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(ILYAUL @ Nov 8 2013, 16:13) *
Коллеги , а давайте в отдельной теме. Эта всё таки про студию

Разделил.
Модератор
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 9 2013, 19:56
Сообщение #29


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

Группа: Свой
Сообщений: 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
maksimp
сообщение Nov 28 2013, 20:35
Сообщение #30


Местный
***

Группа: Участник
Сообщений: 313
Регистрация: 2-07-11
Пользователь №: 66 023



Цитата(sonycman @ Nov 9 2013, 22:56) *
При этом GCC полностью удаляет из полученного кода часть, которая обрабатывает отрицательный результат.

Чудеса оптимизации. Умеет определять, что после деления 0...65535 на 20 получится 0...3276, после преобразования к знаковому будет не отрицательным у ветка для t<0 не нужна.
Цитата(sonycman @ Nov 9 2013, 22:56) *
Код IAR (v6.21):
...
Здесь уже ошибки нет, применяется деление со знаком.
Однако, если скомпилировать не Release код, а Debug, при тех же настройках оптимизации, получается код с беззнаковым делением.
Интересно 05.gif

Увы, IAR не вызывает доверия. Самый худший вариант, когда результат зависит от включения отладки sad.gif.
Go to the top of the page
 
+Quote Post

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

 


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


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