Несколько устав уже от нюансов по поводу интерпретации стандатров различными компиляторами, нашёл всё таки время "добить" код, прогнав его через 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, при тех же настройках оптимизации, получается код с беззнаковым делением.
Интересно
Кейл (uVision v4.72) тоже применяет деление без знака, как и GCC, хотя мне вначале казалось наоборот. Прошу простить за невнимательность

Код
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!