mcheb 0 7 февраля, 2018 Опубликовано 7 февраля, 2018 · Жалоба Решил проверить в GCC uint16_t i; float SigRe[16],*pSigRe; pSigRe = SigRe; for(i=0; i<16; i++) SigRe[i] = 2.*(i+1); for(i=0; i<16; i++) *pSigRe++ = log2f(*pSigRe) * 15.0515; for(i=0; i<16; i++) printf("i = %u SigRe[%u] = %f12.5\n",i,i,SigRe[i]); for(i=0; i<16; i++) SigRe[i] = 2.*(i+1); for(i=0; i<16; i++) SigRe[i] = log2f(SigRe[i]) * 15.0515; for(i=0; i<16; i++) printf("i = %u SigRe[%u] = %f12.5\n",i,i,SigRe[i]); Получил i = 0 SigRe[0] = 30.10300112.5 i = 1 SigRe[1] = 38.90756212.5 i = 2 SigRe[2] = 45.15449912.5 i = 3 SigRe[3] = 50.00000012.5 i = 4 SigRe[4] = 53.95906412.5 i = 5 SigRe[5] = 57.30640412.5 i = 6 SigRe[6] = 60.20600112.5 i = 7 SigRe[7] = 62.76362612.5 i = 8 SigRe[8] = 65.05149812.5 i = 9 SigRe[9] = 67.12113212.5 i = 10 SigRe[10] = 69.01056712.5 i = 11 SigRe[11] = 70.74866512.5 i = 12 SigRe[12] = 72.35790312.5 i = 13 SigRe[13] = 73.85606412.5 i = 14 SigRe[14] = 75.25750012.5 i = 15 SigRe[15] = -1913.32995612.5 i = 0 SigRe[0] = 15.05150012.5 i = 1 SigRe[1] = 30.10300112.5 i = 2 SigRe[2] = 38.90756212.5 i = 3 SigRe[3] = 45.15449912.5 i = 4 SigRe[4] = 50.00000012.5 i = 5 SigRe[5] = 53.95906412.5 i = 6 SigRe[6] = 57.30640412.5 i = 7 SigRe[7] = 60.20600112.5 i = 8 SigRe[8] = 62.76362612.5 i = 9 SigRe[9] = 65.05149812.5 i = 10 SigRe[10] = 67.12113212.5 i = 11 SigRe[11] = 69.01056712.5 i = 12 SigRe[12] = 70.74866512.5 i = 13 SigRe[13] = 72.35790312.5 i = 14 SigRe[14] = 73.85606412.5 i = 15 SigRe[15] = 75.25750012.5 Hello world! Ругается на Prj\Hello\main.c:12:32: warning: operation on 'pSigRe' may be undefined [-Wsequence-point] for(i=0; i<16; i++) *pSigRe++ = log2f(*pSigRe) * 15.0515; Выходит, что нельзя так. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 7 февраля, 2018 Опубликовано 7 февраля, 2018 · Жалоба А еще правильнее написать авторам cppcheck и задать вопрос напрямую.Какой вопрос??? Еще на первой странице выяснили: все описано в Стандарте, cppcheck ругается правильно. Но некоторые уже четвертую страницу бубнят "Я переходил дорогу на красный свет и меня не сбили. Нафига в правилах написали, что переходить на красный нельзя?". А некторые еще и переходят на красный, чтобы убедиться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 7 февраля, 2018 Опубликовано 7 февраля, 2018 · Жалоба ********************************************************************** -O0 000320 490e LDR r1,|L8.860| 000322 6008 STR r0,[r1,#0] ; SigRe ;;;3771 pSigRe = SigRe; 000324 460c MOV r4,r1 ;;;3772 for (uint32_t i = FFT_N; i--; ) { 000326 f44f6680 MOV r6,#0x400 00032a e00f B |L8.844| |L8.812| ;;;3775 *pSigRe++ = log2f(*pSigRe) * 15.0515; 00032c 6820 LDR r0,[r4,#0] 00032e f7fffffe BL log2f 000332 900b STR r0,[sp,#0x2c] 000334 f7fffffe BL __aeabi_f2d 000338 4680 MOV r8,r0 00033a 4a14 LDR r2,|L8.908| 00033c 4b14 LDR r3,|L8.912| 00033e f7fffffe BL __aeabi_dmul 000342 e9cd010c STRD r0,r1,[sp,#0x30] 000346 f7fffffe BL __aeabi_d2f 00034a c401 STM r4!,{r0} |L8.844| 00034c 1e30 SUBS r0,r6,#0 ;3772 00034e f1a60601 SUB r6,r6,#1 ;3772 000352 d1eb BNE |L8.812| |L8.860| DCD SigRe |L8.908| DCD 0x353f7cee |L8.912| DCD 0x402e1a5e ******************************************************************************** -O0 000320 490e LDR r1,|L8.860| 000322 6008 STR r0,[r1,#0] ; SigRe ;;;3771 pSigRe = SigRe; 000324 460c MOV r4,r1 ;;;3772 for (uint32_t i = FFT_N; i--; ) { 000326 f44f6680 MOV r6,#0x400 00032a e010 B |L8.846| |L8.812| ;;;3775 *pSigRe = log2f(*pSigRe) * 15.0515; 00032c 6820 LDR r0,[r4,#0] 00032e f7fffffe BL log2f 000332 900b STR r0,[sp,#0x2c] 000334 f7fffffe BL __aeabi_f2d 000338 4680 MOV r8,r0 00033a 4a14 LDR r2,|L8.908| 00033c 4b14 LDR r3,|L8.912| 00033e f7fffffe BL __aeabi_dmul 000342 e9cd010c STRD r0,r1,[sp,#0x30] 000346 f7fffffe BL __aeabi_d2f 00034a 6020 STR r0,[r4,#0] ;;;3776 pSigRe++; 00034c 1d24 ADDS r4,r4,#4 |L8.846| 00034e 1e30 SUBS r0,r6,#0 ;3772 000350 f1a60601 SUB r6,r6,#1 ;3772 000354 d1ea BNE |L8.812| |L8.860| DCD SigRe |L8.908| DCD 0x353f7cee |L8.912| DCD 0x402e1a5e ******************************************************************************** -O3 -Otime ;;;3775 *pSigRe++ = log2f(*pSigRe) * 15.0515; 000264 f24038ff MOV r8,#0x3ff ;3722 0002d8 4c0a LDR r4,|L8.772| 0002da 4d17 LDR r5,|L8.824| 0002dc 4e17 LDR r6,|L8.828| |L8.734| 0002de 6820 LDR r0,[r4,#0] ;3775 0002e0 f7fffffe BL log2f 0002e4 f7fffffe BL __aeabi_f2d 0002e8 462a MOV r2,r5 ;3775 0002ea 4633 MOV r3,r6 ;3775 0002ec f7fffffe BL __aeabi_dmul 0002f0 f7fffffe BL __aeabi_d2f 0002f4 f8440b04 STR r0,[r4],#4 ;3775 0002f8 f1b80801 SUBS r8,r8,#1 ;3775 0002fc d2ef BCS |L8.734| |L8.772| DCD extram |L8.824| DCD 0x353f7cee |L8.828| DCD 0x402e1a5e ******************************************************************************** -O3 -Otime ;;;3771 pSigRe = SigRe; ;;;3772 for (uint32_t i = FFT_N; i--; ) { ;;;3775 *pSigRe = log2f(*pSigRe) * 15.0515; ;;;3776 pSigRe++; ;;;3777 } 000264 f24038ff MOV r8,#0x3ff ;3722 0002d8 4c0a LDR r4,|L8.772| 0002da 4d17 LDR r5,|L8.824| 0002dc 4e17 LDR r6,|L8.828| |L8.734| 0002de 6820 LDR r0,[r4,#0] ;3775 0002e0 f7fffffe BL log2f 0002e4 f7fffffe BL __aeabi_f2d 0002e8 462a MOV r2,r5 ;3775 0002ea 4633 MOV r3,r6 ;3775 0002ec f7fffffe BL __aeabi_dmul 0002f0 f7fffffe BL __aeabi_d2f 0002f4 f8440b04 STR r0,[r4],#4 ;3775 0002f8 f1b80801 SUBS r8,r8,#1 ;3775 0002fc d2ef BCS |L8.734| |L8.772| DCD extram |L8.824| DCD 0x353f7cee |L8.828| DCD 0x402e1a5e В общем, для Keil нет разницы. Как нет и никакого преимущества писать сразу *SigRe++ = ... Учту замечание CppCheck. Но, чтобы снизошло озарение и просветление, так нет. *********************************************************************** -O3 ;;;3775 *pSigRe++ = log2f(*pSigRe) * 15.0515; 000208 f24035ff MOV r5,#0x3ff 000280 4c09 LDR r4,|L8.680| 000282 4e12 LDR r6,|L8.716| 000284 4f12 LDR r7,|L8.720| |L8.646| 000286 6820 LDR r0,[r4,#0] ;3775 000288 f7fffffe BL log2f 00028c f7fffffe BL __aeabi_f2d 000290 4632 MOV r2,r6 ;3775 000292 463b MOV r3,r7 ;3775 000294 f7fffffe BL __aeabi_dmul 000298 f7fffffe BL __aeabi_d2f 00029c c401 STM r4!,{r0} ;3775 00029e 1e6d SUBS r5,r5,#1 ;3775 0002a0 d2f1 BCS |L8.646| |L8.680| DCD extram |L8.716| DCD 0x353f7cee |L8.720| DCD 0x402e1a5e Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 190 7 февраля, 2018 Опубликовано 7 февраля, 2018 · Жалоба Привел код. Скомпилировал на C++ Builder 2010 и в DevC++. Думаю, пояснения не нужны :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 7 февраля, 2018 Опубликовано 7 февраля, 2018 · Жалоба Усё, таперича проникся. Просвещен. Спасибо всем неравнодушным! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 7 февраля, 2018 Опубликовано 7 февраля, 2018 · Жалоба Я думаю, если ассемблер данного конкретного контроллера поддерживает постинкремент указателей, и компилятор использует это свойство, то результат будет всегда один. Нет, это не так. Это только означает что в данном конкретном случае оптимизатору выгоднее было использовать такой набор команд. Если вдруг окажется, что эта команда находится в цикле со множеством постинкрементных адресаций в пределах одной итерации цикла: p = &array[0]; do { i0 = *p++; ... i1 = *p++; ... i2 = *p++; ... i3 = *p++; } while (); то оптимизирующий компилятор сделает: p = &array[0] - 4; do { LDR R1, [R0, #16]! ... LDR R2, [R0, #4] ... LDR R3, [R0, #8] ... LDR R4, [R0, #12] } while (); потому что все эти команды внутри цикла в сумме по размеру будут == 4+2+2+2 байт - это меньше, чем: do { LDR R1, [R0], #4 ... LDR R2, [R0], #4 ... LDR R3, [R0], #4 ... LDR R4, [R0], #4 } while (); итого == 4+4+4+4 байт. В таких случаях выгоднее (в системе команд Cortex-M) сделать один раз приращение указателя в теле цикла, чем в каждой точке *p++. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 7 февраля, 2018 Опубликовано 7 февраля, 2018 · Жалоба Зависит от типа оптимизации. Пусть хоть весь цикл развернет в линейный код, лишь бы делал, что задумано. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kabdim 0 7 февраля, 2018 Опубликовано 7 февраля, 2018 · Жалоба Удивляет что половина вроде как "опытных" "своих" не знают причин почему так получается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 190 7 февраля, 2018 Опубликовано 7 февраля, 2018 (изменено) · Жалоба Удивляет что половина вроде как "опытных" "своих" не знают причин почему так получается. Для этого и существует форум, ИМХО, для обмена опытом и т.д. Между прочим, такие вещи в книгах особо и не описываются, поэтому даже грамотные специалисты могут и не знать не помнить каких-то подводных камней... Отдельное спасибо jcxz за пример оптимизирующего решения. Я же все никак до ассемблера кортексов не доберусь... Изменено 7 февраля, 2018 пользователем Arlleex Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 7 февраля, 2018 Опубликовано 7 февраля, 2018 · Жалоба Удивляет что половина вроде как "опытных" "своих" не знают причин почему так получается. Просто не пользуются и все такими конструкциями. template<class... Ts> struct overloaded : Ts... {}; template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>; // usage overloaded {[](auto arg) {}, [](double arg) {}}; Многие опытные скажут как это работает? Не пользуешься и не знаешь, ничего стыдного Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 7 февраля, 2018 Опубликовано 7 февраля, 2018 · Жалоба ViKo, учтите замечания анализатора. Зачем вам писать компиляторозависимый код? Keil так сделает, IAR - по другому... Портируете код на PC, к примеру, и какой-нибудь майкрософтовский компилятор использует возможность следовать строгому стандарту и сделает ваш код неработоспособным)))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kabdim 0 7 февраля, 2018 Опубликовано 7 февраля, 2018 · Жалоба Многие опытные скажут как это работает? Не пользуешься и не знаешь, ничего стыдного Сравнили выстрелы в ногу от постинкремента и приоритета операций, которые с времен чистого С тянутся с новыми фишками 17 версии. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 7 февраля, 2018 Опубликовано 7 февраля, 2018 · Жалоба Сравнили выстрелы в ногу от постинкремента и приоритета операций, которые с времен чистого С тянутся с новыми фишками 17 версии. Ну не пишут опытные программеры конструкции как ТС предложил и все. Зачем? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kabdim 0 7 февраля, 2018 Опубликовано 7 февраля, 2018 · Жалоба Собственно к тем кто не пишет никаких претензий нет, огорчение вызывают те кто готов такое писать не обладая знаниями. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 7 февраля, 2018 Опубликовано 7 февраля, 2018 · Жалоба Согласен Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться