zltigo 2 20 августа, 2011 Опубликовано 20 августа, 2011 · Жалоба Повторяю еще раз. Незачем :). Я и первый раз ответ понял. Когда я пишу макрос то.... В данном случае это НЕ макрос, а отвечать почему-то Вы начали мне, а не Автору. Что касается обертки всего чего попало макросообразного во while(0), то в ответ на такое вменяемый компилятор встретив бессмысленное выражение будет генерить warning. Посему злоупотреблять, а то употреблять по причине решения притянутой за уши "проблемы", совершенно не следует. Совершенно достаточно заключать многострочные макросы в фигурные скобки. В этом случае либо он будет работать, как положено, либо получите (если вдруг забыли :), что это FUNCTION() у Вас макрос ) сообщение об ошибке и напишите просто и без затей c фигурными скобками: if( ... ) { FUNCTION(); } else ...... вместо if( ... ) FUNCTION(); else ...... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Буян 0 20 августа, 2011 Опубликовано 20 августа, 2011 · Жалоба Что касается обертки всего чего попало макросообразного во while(0), то в ответ на такое вменяемый компилятор встретив бессмысленное выражение будет генерить warning. Видимо GCC невменяемый компилятор... do { unsigned char i; i=PORTC.IN; 3dc: 80 91 48 06 lds r24, 0x0648 i+=17; 3e0: 8f 5e subi r24, 0xEF ; 239 PORTC.OUT=i; 3e2: e0 e4 ldi r30, 0x40 ; 64 3e4: f6 e0 ldi r31, 0x06 ; 6 3e6: 84 83 std Z+4, r24 ; 0x04 } while(0); PORTC.OUT=PORTC.IN+17; 3dc: 80 91 48 06 lds r24, 0x0648 3e0: 8f 5e subi r24, 0xEF ; 239 3e2: e0 e4 ldi r30, 0x40 ; 64 3e4: f6 e0 ldi r31, 0x06 ; 6 3e6: 84 83 std Z+4, r24 ; 0x04 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 20 августа, 2011 Опубликовано 20 августа, 2011 · Жалоба Видимо GCC невменяемый компилятор... Да :(. Встретив бессмысленную языковую конструкцию он молча без предупреждений ее выкинул. А может программист совершенно другое имел ввиду и банально описался. Есть варианты и похуже - компилятор может и оставить ошметки в коде от таких трюков :(. Аналогично некорректно молча игнорировать, к сожалению, широко бездумно применяемое while( 1 ){.....} Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 20 августа, 2011 Опубликовано 20 августа, 2011 · Жалоба Я как-то даже не задумывался что умудрюсь пересечься с какими либо объявлениями. Хотя теоретически это реально. Не Вы пересечётесь (хотя, можете вполне). Это используется в заголовочных файлах стандартной библиотеки, чтобы не пересечся с Вашими оперделениями, которые не должны начинаться с подчёркивания, например. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 20 августа, 2011 Опубликовано 20 августа, 2011 · Жалоба чтобы не пересечся с.. Да бог с ними с пересечениями - компилятор выругается в конце концов. Дело в банальном ненужном коверкании и неудобовосприятии. С подчеркивания имеет смысл давать имена тому, что не должно употребляться в явном виде - функции/макросы, которые используются только, например, как, inline в другие и не имеющие самостоятельного смысла. Дефиниции, которые прикрывают от повторного включения заголовочные файлы. Какие-то вещи вызывающие побочные эффекты. Короче, то, что является чем-то запретным/ограниченным для обычного использования в программе и требующее особых причин и внимательности при использовании. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ARV 1 20 августа, 2011 Опубликовано 20 августа, 2011 · Жалоба Да :( . Встретив бессмысленную языковую конструкцию он молча без предупреждений ее выкинул. А может программист совершенно другое имел ввиду и банально описался. Есть варианты и похуже - компилятор может и оставить ошметки в коде от таких трюков :( . Аналогично некорректно молча игнорировать, к сожалению, широко бездумно применяемое while( 1 ){.....}что-то я не понял сии выпады... поясните, пожалуйста, о чем конкретно вы говорите? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 20 августа, 2011 Опубликовано 20 августа, 2011 · Жалоба что-то я не понял сии выпады... поясните, пожалуйста, о чем конкретно вы говорите? что-то я не понял сии вопросы... поясните, пожалуйста, о чем конкретно вы спрашиваете? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ARV 1 21 августа, 2011 Опубликовано 21 августа, 2011 · Жалоба что-то я не понял сии вопросы... поясните, пожалуйста, о чем конкретно вы спрашиваете?что ж... Встретив бессмысленную языковую конструкцию он молча без предупреждений ее выкинул. А может программист совершенно другое имел ввиду и банально описался. существуют компиляторы, которые угадывают, что хотел программист на основе того, что он написал? Есть варианты и похуже - компилятор может и оставить ошметки в коде от таких трюков.о чем тут речь? хотелось бы на примере Аналогично некорректно молча игнорировать, к сожалению, широко бездумно применяемое while( 1 ){.....}а с while(1) что не так? P.S. вопросы задаю не из потаенного желания уязвить, но из желания узнать правдуновое о GCC, в частности, avr-gcc. век еще не прожил, но учусь все время... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 21 августа, 2011 Опубликовано 21 августа, 2011 (изменено) · Жалоба Забыл привести одну конструкцию, используемую в Protothreads Итак, макрос #define PT_WAIT_UNTIL(pt, condition) \ do { \ LC_SET((pt)->lc); \ if(!(condition)) { \ return PT_WAITING; \ } \ } while(0) , где LC_SET() #define LC_SET(s) s = __LINE__; case __LINE__: Поясню для тех, кому не близки Protothreads Общий вариант построения функции с переопределяемой точкой входа - на машине Даффа, имеет упрощенный вид unsigned int protothread(unsigned int pc) { switch(pc) { case 0: // отсюда идет инициализация, к делу не относится //далее, вставим ожидание события PT_WAIT_UNTIL(), получим, разворачивая макрос и немного упрощая концепцию do{ pc = __LINE__; case __LINE__:; if(!condition) return pc; }while(0); } return pc; } И такая чехарда воспринимается компиляторами! Несмотря на то, что по указанному case __LINE__: мы попадем внутрь блока do{}while(0) Это я к чему. Кто нить знает компилятор, который такое "не хавает"? Изменено 21 августа, 2011 пользователем _Pasha Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ARV 1 21 августа, 2011 Опубликовано 21 августа, 2011 · Жалоба Кто нить знает компилятор, который такое "не хавает"?и чего тут хорошего? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 21 августа, 2011 Опубликовано 21 августа, 2011 · Жалоба и чего тут хорошего? Я - не знаю, у меня другая модель этих пресловутых local continuations, свободная от подобных штукесов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 21 августа, 2011 Опубликовано 21 августа, 2011 · Жалоба существуют компиляторы, которые угадывают, что хотел программист на основе того, что он написал? Да, практически все :). Вопрос только в том, генерить или нет компилятору предупреждения, когда он видит бессмысленные с точки зрения генерации кода конструкции, например, все те-же do{...}while(0) и while( 1 ){...} Все ведь не все так безобидно с отсутствием предупреждений при выражениях которые верны всегда. Например: while( value > 1 ){...} где #define value 2 Это уже практически наверняка какой-то ляп программиста, о котором надо предупреждать. о чем тут речь? хотелось бы на примере Сейчас примера специально искать не буду, и даже, надеюсь, что среди коммерческих компиляторов таких уже нет, но когда компиляторы десяток-другой лет тому назад были не такими умными, то за примерами ходить далеко не надо было :(. а с while(1) что не так? Не так, что используется условие которое верно всегда. Да я понимаю, что это многим уже страшно привычно и не бросается у глаза, и компиляторы давно уже не генерят лишнего кода. Но тем не менее пропускать такое без notes/warning не красиво. А писать такое неграмотно, хотя все поймут, что написавший "ложить" сахар, имел ввиду класть сахар в чай. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 21 августа, 2011 Опубликовано 21 августа, 2011 · Жалоба И такая чехарда воспринимается компиляторами! Несмотря на то, что по указанному case __LINE__: мы попадем внутрь блока do{}while(0) Это я к чему. Кто нить знает компилятор, который такое "не хавает"? А разве он после этого будет иметь право называться компилятором языка С ? Дабы не иметь необходимости отвечать «а почему вы спрашиваете?» на «а Вы всегда отвечаете вопросом на вопрос?» : 3.6.4 Selection statements Syntax selection-statement: if ( expression ) statement if ( expression ) statement else switch ( expression ) statement 3.6.4.2 The switch statement ... Semantics A switch statement causes control to jump to, into, or past the statement that is the switch body, depending on the value of a controlling expression, and on the presence of a default label and the values of any case labels on or in the switch body. A case or default label is accessible only within the closest enclosing switch statement. После намёка машиной даффа на то, что надо ещё раз прочесть соответствующий раздел стандарта, я это прочёл так: В switch ( expression ) statement нет никаких уточнений по поводу того, что за statement имеется ввиду. Обычно там стоит compound statement. Кстати, в начале compound statement может стоять declaration-list: volatile int i; void moo(int u) { switch (u) { // Это начало обычного compound statement, а не неотъемлемая часть switch volatile int j; case 3: j = u; u = i; i = j + u; break; case 4: j = -u; u = -i; i = j + u; break; } } Главное, чтобы новая переменная инициализировалась в каждой ветке. Или была static Но никто не мешает поставить туда другой statement, например, цикл... Или... Или обычное, не-составное выражение! void foo(int u) { switch (u) case 3: ++i; } Что компилируется, и компилиурется (естественно) в аналогичное void foo2(int u) { if (u == 3) ++i; } Конечно, такой switch-powered-if, пришедший из Incredible Machine, никому не нужен. Но хорошо демонстирурует, что statement не обязан быть только compound. Так что switch имеет право ходить везде, где имеет право ходить goto. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
777777 0 21 августа, 2011 Опубликовано 21 августа, 2011 · Жалоба Аналогично некорректно молча игнорировать, к сожалению, широко бездумно применяемое while( 1 ){.....} А что это вы против while(1) взъелись? В любой программе для микроконтроллера есть бесконечный цикл. Как вы его кодите? Пишите в конце goto begin? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 21 августа, 2011 Опубликовано 21 августа, 2011 · Жалоба for(;;) { // endless loop } Совсем-совсем формально, возможно, и не отличается от while(1) {} (по стандарту для for(;;) «An omitted expression-2 is replaced by a nonzero constant»), но в качестве примера бесконечного цикла в C99 приведён именно этот вариант. В более ранних книгах тоже. Не помню, чтобы я когда-либо писал while(1) :-) Думаю, это рецидив паскаля :-) Ни в каких компиляторах for(;;) никогда не оставляло хвостов недооптимизации в духе того, что бывало от while(1), например jmp cy_end cy_start: ... cy_end: ; типа оптимизировали и пред-проверку поставили в конце, чтобы уменьшить число переходов ; потом увидели, что условие константа и проверку убрали ; но убрать jmp cy_end в начале забыли jmp cy_start Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться