Сергей Борщ 140 21 октября, 2008 Опубликовано 21 октября, 2008 · Жалоба Чтение из переменной очевидно, когда оно стоит справа от знака присваивания.К слову: совершенно неочевидно, что занесение значения в переменную слева от знака присваивания является лишь побочным эффектом опрератора "=", но это так и есть. 1) Согласно стандарту языка для чтения volatile переменной var достаточно написать var; Кому интересно, могу подкрепить это цитатами из стандарта. Очень интересно. ИАР для АРМов, версии 4.30 точно (более старшие не проверял), с легкостью выкидывает такие обращения. ReAl объяснил это мутностью стандарта в этой части. Самому искать было лень. Но раз вы предлагаете найти - с удовольствием почитаю цитаты.- бороться с предупреждениями компилятора при присваивании вспомогательной переменной dummy = var; Все встречавшиеся мне компиляторы убирали предупреждение при добавлении строчки dummy = dummy; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 21 октября, 2008 Опубликовано 21 октября, 2008 · Жалоба Очень интересно. ИАР для АРМов, версии 4.30 точно (более старшие не проверял), с легкостью выкидывает такие обращения. Любой вменяемый компилятор выкидывает, но ЕСЛИ НЕ volatile. В данном случае это volatile, а не для volatile - выкидывает правильнно, ибо пустое и бессмысленное действие. ReAl объяснил это мутностью стандарта в этой части. Никакой мутности в отношении volatile переменных в C99 нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 140 21 октября, 2008 Опубликовано 21 октября, 2008 · Жалоба Любой вменяемый компилятор выкидывает, но ЕСЛИ НЕ volatile.Вот сейчас специально поставлю ИАР и приведу листинг. Именно volatile переменную. Момент... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 21 октября, 2008 Опубликовано 21 октября, 2008 · Жалоба Все встречавшиеся мне компиляторы убирали предупреждение при добавлении строчки dummy = dummy; Наиблее часто встречающийся :( с "финтами", но безграмотный вариант :(. Однозначный и независимый от компилятора и опимизации: (void)dummy; Вот сейчас специально поставлю ИАР и приведу листинг. Именно volatile переменную. Момент... Не стоит :). Не получится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 140 21 октября, 2008 Опубликовано 21 октября, 2008 · Жалоба Не стоит :). Не получится.Если бы не получалось, я бы в эту ветку не писал: Пожалуйста: OS_INTERRUPT void Timer_ISR() { OS::TISRW ISRW; T1IR; // = T1IR; // clear int flag IO0SET = (1 << 29); На строку с комментарием предупреждение: Warning[Pe174]: expression has no effect D:\Projects\Req\scmRTOS\Samples\LPC2xxx\1-EventFlag\Src\main.cpp 108 ####################################################################### ####### # # # IAR ARM ANSI C/C++ Compiler V4.30A/W32 EVALUATION 21/Oct/2008 23:47:48 # # Copyright 1999-2005 IAR Systems. All rights reserved. # # # # Cpu mode = interwork # # Endian = little # # Stack alignment = 4 # # Source file = D:\Projects\Req\scmRTOS\Samples\LPC2xxx\1-EventFlag\ # # Src\main.cpp # # Command line = D:\Projects\Req\scmRTOS\Samples\LPC2xxx\1-EventFlag\ # # Src\main.cpp -D LPC2119 -lCN # # D:\Projects\Req\scmRTOS\Samples\LPC2xxx\1-EventFlag\ # # List\ -o D:\Projects\Req\scmRTOS\Samples\LPC2xxx\1-E # # ventFlag\Obj\ -s9 --debug --cpu_mode thumb --endian # # little --cpu ARM7TDMI-S --stack_align 4 --interwork # # -e --fpu None --eec++ --dlib_config # # D:\Programs\IAR\arm\LIB\dl4tptinl8n.h -I # # D:\Projects\Req\scmRTOS\Samples\LPC2xxx\1-EventFlag\ # # Src\ -I D:\Projects\Req\scmRTOS\Samples\LPC2xxx\1-Ev # # entFlag\..\scmRTOS\Common\ -I # # D:\Projects\Req\scmRTOS\Samples\LPC2xxx\1-EventFlag\ # # ..\scmRTOS\ARM7\ -I D:\Programs\IAR\arm\INC\ # # List file = D:\Projects\Req\scmRTOS\Samples\LPC2xxx\1-EventFlag\ # # List\main.lst # # Object file = D:\Projects\Req\scmRTOS\Samples\LPC2xxx\1-EventFlag\ # # Obj\main.r79 # # # # # ############################################################################## ......................... \ In segment DATA_AN, at 0xe0008000 \ <unnamed> volatile __data _A_T1IR \ _A_T1IR: \ 00000000 DS8 4 ......................... 104 OS_INTERRUPT void Timer_ISR() 105 { \ ??Timer_ISR: \ 00000000 04E04EE2 SUB LR,LR,#+0x4 \ 00000004 1F502DE9 STMDB SP!,{R0-R4,R12,LR} ;; Push 106 OS::TISRW ISRW; \ 00000008 70409FE5 LDR R4,??Timer_ISR_1 ;; Kernel \ 0000000C 1400D4E5 LDRB R0,[R4, #+0x14] \ 00000010 010080E2 ADD R0,R0,#+0x1 \ 00000014 1400C4E5 STRB R0,[R4, #+0x14] 107 108 T1IR; // = T1IR; // clear int flag 109 IO0SET = (1 << 29); \ 00000018 4E02A0E3 MOV R0,#-536870908 \ 0000001C A00B80E3 ORR R0,R0,#+0x28000 \ 00000020 8015A0E3 MOV R1,#+0x20000000 \ 00000024 001080E5 STR R1,[R0, #+0] Компилятор не такой и старый, сильно моложе чем C99 не говоря уже о C89: IAR C/C++ Compiler for ARM 4.30A Evaluation (4.30.1.237) D:\Programs\IAR\arm\bin\iccarm.exe 09.02.2005 21:13:44, 9539584 bytes Поэтому и хочется увидеть цитату из стандарта. А самому искать лень ;) GCC даже в версии 3.2.3 от 2003(?) года не выкидывает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 21 октября, 2008 Опубликовано 21 октября, 2008 · Жалоба На строку с комментарием предупреждение: Warning[Pe174]: expression has no effect Это типичное сообщение при выкидывании не volatile переменной. Просто T1IR неведомо как описан. Давай чистый эксперимент. volatile int dummy = 0; ..... function() { dummy; Поскольку я пишу на "С" уже лет 20, именно так, в том числе и под IAR, года 4, то в результате СИШНОГО КОМПИЛЯТОРА я более, чем уверен. В догонку: ############################################################################## # # # IAR ARM ANSI C/C++ Compiler V4.42A/W32 22/Oct/2008 01:13:05 # # Copyright 1999-2005 IAR Systems. All rights reserved. # # # # Cpu mode = arm # # Endian = little # # Stack alignment = 8 # # Source file = D:\ARM_WORK\auc\MAIN\fiqhandl.c # # Command line = D:\ARM_WORK\auc\MAIN\fiqhandl.c -D LPC2000_IAR -lC # # D:\ARM_WORK\auc\Works_Kernel\List\ -lA # # D:\ARM_WORK\auc\Works_Kernel\List\ --remarks -o # # D:\ARM_WORK\auc\Works_Kernel\Obj\ -s9 --cpu_mode # # arm --endian little --cpu ARM7TDMI-S --stack_align # # 8 --warnings_affect_exit_code # # --no_path_in_file_macros --migration_preprocessor_ex # # tensions -e --require_prototypes --fpu None # # --dlib_config "D:\IAR\Embedded # # Workbench\arm\LIB\dl4tpannl8n.h" -I # # D:\ARM_WORK\auc\..\COMMON\RTOS\portable\IAR\LPC2000\ # # -I D:\ARM_WORK\auc\..\COMMON\RTOS\include\ -I # # D:\ARM_WORK\auc\..\COMMON\include\ -I # # D:\ARM_WORK\auc\main\include\ -I "D:\IAR\Embedded # # Workbench\arm\INC\" --inline_threshold=8 # # List file = D:\ARM_WORK\auc\Works_Kernel\List\fiqhandl.lst # # Object file = D:\ARM_WORK\auc\Works_Kernel\Obj\fiqhandl.r79 # # # # # ############################################################################## D:\ARM_WORK\auc\MAIN\fiqhandl.c 1 2 #include <stdlib.h> 3 #include "RTOS.h" \ In segment DATA_AN, at 0xe01fc140 \ union <unnamed> volatile __data _A_EXTINT \ _A_EXTINT: \ 00000000 DS8 4 4 #include "fiqhandl.h" 5 \ In segment DATA_Z, align 4, align-sorted 6 volatile int dummy1; \ dummy1: \ 00000000 DS8 4 \ In segment DATA_Z, align 4, align-sorted 7 int dummy2; \ dummy2: \ 00000000 DS8 4 8 9 //--------------------------------------------------------------------------- 10 // 11 //--------------------------------------------------------------------------- \ In segment CODE, align 4, keep-with-next 12 __fiq __arm void FIQ_ISR_handler(void) 13 { 14 15 dummy1; \ FIQ_ISR_handler: \ 00000000 14809FE5 LDR R8,??FIQ_ISR_handler_0 ;; dummy1 \ 00000004 008098E5 LDR R8,[R8, #+0] 16 dummy2; ^ Warning[Pe174]: expression has no effect 17 18 Оба варианта - c выкидыванием и без. Более старях компиляторов не держу, но если что, то и на самом старом и кривом имеющимся у меня BCC 3.1 будет тоже самое. Ибо вариантов нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 21 октября, 2008 Опубликовано 21 октября, 2008 · Жалоба Попробовал на древнем: # IAR Atmel AVR C/EC++ Compiler V3.20C/W32, Evaluation Version 22/Oct/2008 01:26:48 # Тоже всё ок: volatile unsigned char my_dummy; void main(void) { my_dummy; } //==================================================== листинг: 85 my_dummy; \ 00000004 .... LDI R26,LOW(??statetext) \ 00000006 .... LDI R27,(??statetext) >> 8 \ 00000008 01FD MOVW R31 : R30,R27 : R26 \ 0000000A 8501 LDD R16,Z+9 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 140 21 октября, 2008 Опубликовано 21 октября, 2008 · Жалоба Это типичное сообщение при выкидывании не volatile переменной. Просто T1IR неведомо как описан.Я специально дал вырезку из листинга, в которой он сам эту переменную описывает как volatile: \ In segment DATA_AN, at 0xe0008000 \ <unnamed> volatile __data _A_T1IR \ _A_T1IR: \ 00000000 DS8 4 По поводу типичности сообщений один человек очень красиво написал на AVRFreaks: In the case of warnings, the answer never lies in the C standard. The C standard does not require any warnings. We are trying to read the minds of the gods. As a rule, a compiler issues a warning when you have done something that is allowed, but the compiler suspects might not be what you intended. Давай чистый эксперимент.Не вопрос:volatile int dummy = 0; void function() { dummy; } //--------------------------------------------------------------------------- OS_INTERRUPT void Timer_ISR() { OS::TISRW ISRW; T1IR; // = T1IR; // clear int flag Warning[Pe174]: expression has no effect D:\Projects\Req\scmRTOS\Samples\LPC2xxx\1-EventFlag\Src\main.cpp 106 Warning[Pe174]: expression has no effect D:\Projects\Req\scmRTOS\Samples\LPC2xxx\1-EventFlag\Src\main.cpp 113 Поскольку я пишу на "С" уже лет 20, именно так, в том числе и под IAR, года 4, то в результате СИШНОГО КОМПИЛЯТОРА я более, чем уверен.Я не хочу спорить. ИАР вполне себе сишный компилятор и становится все лучше год от года. Я лишь хочу разобраться - это была бага или есть фича. Если стандарт описывает поведение однозначно - бага. Если нет - фича, и каждую версию каждого компилятора надо будет проверять на необходимость workaround с временной переменной, что я и делаю пока не разобрался в этом вопросе досконально. И как ни крути, хоть вариант без временной переменной красив, но, как видим, не всегда работает. А вариант с временной переменной работает всегда. Следовательно надо разобраться, кто виноват в непортируемости - компилятор, который не соответствует стандарту или программист, понадеявшийся на нерегламентируемое стандартом поведение компилятора.В догонку:В новой версии behaviour изменился :) Все, спать. Иначе придется самим в стандарте копаться ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 21 октября, 2008 Опубликовано 21 октября, 2008 · Жалоба ИАР вполне себе сишный компилятор и.... Тем не менее, ты компилишь П Л Ю С О В Ы М (точнее недоплюсовым :( ) компилятором, почему-то рассуждая о C99. Кроме того, ты получил более, чем вменяемый Warning. ...но, как видим, не всегда работает Я бы поверил, в баг конкретного компилятора, если-бы не работал и с этой версией компилятора, причем гарантированно, многократно и постоянно использовал и использую, как минимум: SSPDR; для очистки FIFO SSP при полудуплексной передаче. Хидеры традиционно использую самописные. По поводу типичности сообщений один человек очень красиво написал на AVRFreaks: В данном случае я говорю о типичном собщении совершенно конкретного компилятора. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 140 21 октября, 2008 Опубликовано 21 октября, 2008 · Жалоба Тем не менее, ты компилишь ПЛЮСОВЫМ компилятором.В точку. Попробовал без плюсов - варнинга нет, чтение есть. Придется штудировать и плюсовый стандарт :crying: Не думал, что в этом вопросе он отличается от неплюсового. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 21 октября, 2008 Опубликовано 21 октября, 2008 · Жалоба Не думал, что в этом вопросе он отличается от неплюсового. Не думаю, что отличается, поскольку это совершенно естественное-разумное поведение. Любое другое не берусь даже хоть как-то объяснить...Полубаг "старого" компилятора :( ? P.S. Попробовал. Любая версия V4-V5 плюсовых компиляторов от IAR выдает warning. Странно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johnny81 0 22 октября, 2008 Опубликовано 22 октября, 2008 · Жалоба Однозначный и независимый от компилятора и опимизации: (void)dummy; Вы знаете, попробовал - не работает. Все равно ворнинг. IAR AVR 4.3 (EEC++). Код: byte dummy; dummy = UDR0; dummy = UDR0; dummy = UDR0; (void) dummy; UDR0 - из стандартного иаровского хидера: SFR_B_R(0x1F, AVR) Expands to: * __io union { * unsigned char AVR; // The sfrb as 1 byte * struct { // The sfrb as 8 bits * unsigned char AVR_Bit0:1, * AVR_Bit1:1, * AVR_Bit2:1, * AVR_Bit3:1, * AVR_Bit4:1, * AVR_Bit5:1, * AVR_Bit6:1, * AVR_Bit7:1; * }; * } @ 0x1F; SFR_B_R(0x0C, UDR0) /* USART0 I/O Data Register */ Ворнинг давится только dummy=dummy :) PS начал читать тему - думал можно будет избавиться от этого некрасивого кода :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 22 октября, 2008 Опубликовано 22 октября, 2008 · Жалоба Вы знаете, попробовал - не работает. Все равно ворнинг. IAR AVR 4.3 (EEC++). Код: byte dummy; dummy = UDR0; dummy = UDR0; dummy = UDR0; (void) dummy; UDR0 - из стандартного иаровского хидера: ... Ворнинг давится только dummy=dummy :) PS начал читать тему - думал можно будет избавиться от этого некрасивого кода :( В Вашем случае прочитать UDR0 без dummy можно и так: if (UDR0); Правда не знаю насколько это читабельно смотрится. На любителя. В плюсах работает и я уже привык. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 22 октября, 2008 Опубликовано 22 октября, 2008 · Жалоба IAR AVR 4.3 (EEC++)..... Ну что я могу сказать - много значит cтранностей в IARовском недоплюсовом компиляторе :(. Подчеркиваю еще раз ПЛЮСОВОМ, а тема начинслась как C/C99. Если var; я в своих плюсовых программах использую редко, поскольку от железа они обычно далеки, то уж (void)var; ввиде макросика USED(var) - в процессе написания ну очень часто. При этом С компилятор от IAR ведет себя абсолютно ожидаемо, впрочем, как и абсолютно все C используемые мной за долгие годы. В оправдание плюсового IAR, могу сказать только то, что warnings он тем не менее генерит... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 10 ноября, 2008 Опубликовано 10 ноября, 2008 · Жалоба ReAl объяснил это мутностью стандарта в этой части. Самому искать было лень.Ой, не помню... Кажется, разночтение было на тему - обязательно ли в цепочке int a; volatile int v; a = v = 0; для записи в a зачитывать из v. Согласно стандарту значением присваивающего выражения есть значение, которое будет записано в левую часть после присваивания. Я утверждал, что в случае volatile-переменной значение неизвестно и нужно перезачитать. Но какой-то компилятор радостно в таком случае явно писал нули во все переменные, что на мой взгляд неправильно. В каком-то обсуждении (RU.C-CPP или ещё где-то) было сказано, что смысл строки стандарта не "что там будет сидеть после записи", а "что туда будет записано", а это не зависит от volatile-ности. Я не стал разбираться дальше, "юридический английский" у меня не настолько... :-( Впрочем, поскольку я всё равно был уверен, что надо перезачитывать, я всё равно не использовал значение присваивающего выражения, если в левой части volatile, так как это снижает читаемость - глаз воспринимает как значение правую часть, а реально будет прочитанное из левой. т.е. не использовал while( (volatile_var = var) ), function( volatile_var = var), return (volatile_var = var); Однако считаю, что в случае отдельно стоящей volatile-переменной в духе UDR; компилятор должен провести все действия, необходимые для вычисления выражения (в данном случае только прочесть переменую, в случае с UDR+1; - прочесть и прибавить единицу), а только потом обнаружить, что результат-то никому не нужен и начать оптимизатором "отматывать" назад ненужные действия - пока не упрётся в запрет, поставленный квалификатором volatile. Т.е. чтение volatile-переменной должно остаться. Если какой-то компилятор этого не делает (это тоже, кажется, где-то в аське обсуждалось), то надо внимательно ещё раз прочесть стандарт и попытаться поругаться. Без финтов - это отлично, но!!! - очень непривычно. Чтение из переменной очевидно, когда оно стоит справа от знака присваивания. И когда этот знак опущен это и вызывает недоумение и неприятие.А многие не понимают указателей. А у многих вызывает недоумение запись value = ( flag ? sin : cos)(x); несмотря на то, что она, на мой взгялд, гораздо более читабельна, чем алгол-68 value := if flag then sin else cos fi (x) Если из С повыбрасывать всё то, что вызывает недоумение у новичков, то что останется? volatile int x; ... x ? : x; Прочесть x, если он равен нулю - прочесть его ещё раз. С прочитанными значениями больше ничего не делать. Коллеге zltigo респект за неординарный подход.Подход правильный, называется "знать инструмент, которым пользуешся". Итак, итоги: ... 2) Очевидно, что такой код не проходит тест "даже моя бабушка поймёт, что это значит". Другими словами, читаемость кода страдает. Читаемость кода завиит от подготовки читающего. Так можно дойти и до "отмены" ++ и переходу от ++i к i = i + 1; (во всяком случае побыстрее запретить применение i++, так как это вообще непонятно). Вменяемый человек, наткнувшись первый раз, при помощи стандарта либо более опытных товарищей разберётся и дальше для него читаемость будет нормальная. На строку с комментарием предупреждение: Warning[Pe174]: expression has no effect D:\Projects\Req\scmRTOS\Samples\LPC2xxx\1-EventFlag\Src\main.cpp 108Странно... Всё-таки странно. Может всё-же пройтись ещё по стандарту и попробовать с ними поругаться? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться