Перейти к содержанию
    

Передача параметров в функцию.

Повторяю еще раз.

Незачем :). Я и первый раз ответ понял.

Когда я пишу макрос то....

В данном случае это НЕ макрос, а отвечать почему-то Вы начали мне, а не Автору. Что касается обертки всего чего попало макросообразного во while(0), то в ответ на такое вменяемый компилятор встретив бессмысленное выражение будет генерить warning. Посему злоупотреблять, а то употреблять по причине решения притянутой за уши "проблемы", совершенно не следует. Совершенно достаточно заключать многострочные макросы в фигурные скобки. В этом случае либо он будет работать, как положено, либо получите (если вдруг забыли :), что это FUNCTION() у Вас макрос ) сообщение об ошибке и напишите просто и без затей c фигурными скобками:

if( ... )

{ FUNCTION();

}

else

......

 

вместо

if( ... )

FUNCTION();

else

......

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что касается обертки всего чего попало макросообразного во 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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Видимо GCC невменяемый компилятор...

Да :(. Встретив бессмысленную языковую конструкцию он молча без предупреждений ее выкинул. А может программист совершенно другое имел ввиду и банально описался. Есть варианты и похуже - компилятор может и оставить ошметки в коде от таких трюков :(. Аналогично некорректно молча игнорировать, к сожалению, широко бездумно применяемое while( 1 ){.....}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я как-то даже не задумывался что умудрюсь пересечься с какими либо объявлениями. Хотя теоретически это реально.

Не Вы пересечётесь (хотя, можете вполне). Это используется в заголовочных файлах стандартной библиотеки, чтобы не пересечся с Вашими оперделениями, которые не должны начинаться с подчёркивания, например.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

чтобы не пересечся с..

Да бог с ними с пересечениями - компилятор выругается в конце концов. Дело в банальном ненужном коверкании и неудобовосприятии. С подчеркивания имеет смысл давать имена тому, что не должно употребляться в явном виде - функции/макросы, которые используются только, например, как, inline в другие и не имеющие самостоятельного смысла. Дефиниции, которые прикрывают от повторного включения заголовочные файлы. Какие-то вещи вызывающие побочные эффекты. Короче, то, что является чем-то запретным/ограниченным для обычного использования в программе и требующее особых причин и внимательности при использовании.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да :( . Встретив бессмысленную языковую конструкцию он молча без предупреждений ее выкинул. А может программист совершенно другое имел ввиду и банально описался. Есть варианты и похуже - компилятор может и оставить ошметки в коде от таких трюков :( . Аналогично некорректно молча игнорировать, к сожалению, широко бездумно применяемое while( 1 ){.....}
что-то я не понял сии выпады... поясните, пожалуйста, о чем конкретно вы говорите?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

что-то я не понял сии выпады... поясните, пожалуйста, о чем конкретно вы говорите?

что-то я не понял сии вопросы... поясните, пожалуйста, о чем конкретно вы спрашиваете?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

что-то я не понял сии вопросы... поясните, пожалуйста, о чем конкретно вы спрашиваете?
что ж...

Встретив бессмысленную языковую конструкцию он молча без предупреждений ее выкинул. А может программист совершенно другое имел ввиду и банально описался.
существуют компиляторы, которые угадывают, что хотел программист на основе того, что он написал?

 

Есть варианты и похуже - компилятор может и оставить ошметки в коде от таких трюков.
о чем тут речь? хотелось бы на примере

 

Аналогично некорректно молча игнорировать, к сожалению, широко бездумно применяемое while( 1 ){.....}
а с while(1) что не так?

 

P.S. вопросы задаю не из потаенного желания уязвить, но из желания узнать правдуновое о GCC, в частности, avr-gcc. век еще не прожил, но учусь все время...

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Забыл привести одну конструкцию, используемую в 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)

Это я к чему. Кто нить знает компилятор, который такое "не хавает"?

Изменено пользователем _Pasha

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кто нить знает компилятор, который такое "не хавает"?
и чего тут хорошего?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

и чего тут хорошего?

Я - не знаю, у меня другая модель этих пресловутых local continuations, свободная от подобных штукесов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

существуют компиляторы, которые угадывают, что хотел программист на основе того, что он написал?

Да, практически все :). Вопрос только в том, генерить или нет компилятору предупреждения, когда он видит бессмысленные с точки зрения генерации кода конструкции, например, все те-же do{...}while(0)

и while( 1 ){...}

Все ведь не все так безобидно с отсутствием предупреждений при выражениях которые верны всегда. Например:

while( value > 1 ){...}

где

#define value 2

Это уже практически наверняка какой-то ляп программиста, о котором надо предупреждать.

 

о чем тут речь? хотелось бы на примере

Сейчас примера специально искать не буду, и даже, надеюсь, что среди коммерческих компиляторов таких уже нет, но когда компиляторы десяток-другой лет тому назад

были не такими умными, то за примерами ходить далеко не надо было :(.

а с while(1) что не так?

Не так, что используется условие которое верно всегда. Да я понимаю, что это многим уже страшно привычно и не бросается у глаза, и компиляторы давно уже не генерят лишнего кода. Но тем не менее пропускать такое без notes/warning не красиво. А писать такое неграмотно, хотя все поймут, что написавший "ложить" сахар, имел ввиду класть сахар в чай.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И такая чехарда воспринимается компиляторами! Несмотря на то, что по указанному 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.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Аналогично некорректно молча игнорировать, к сожалению, широко бездумно применяемое while( 1 ){.....}

 

А что это вы против while(1) взъелись? В любой программе для микроконтроллера есть бесконечный цикл. Как вы его кодите? Пишите в конце goto begin?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...