do {} while (0) зачем?

Приветствую всех, коллеги!

Задумали сделать одну разаработку на блекфине, с uCLinux на борту. Сам я с Линуксом не сильно знаком (на работе поставил debian на роутер, на нем и тренируюсь), поэтому есть пара вопросов:

1) Кому не лень иногда мылом или аськой отвечать на глупые вопросы про заточке uCLinux под мое железо, сборку инструментов и т.д.? 2) В исходниках Линукса встречается такая конструкция: #define SOME_THING \ do { \ func(arg1,arg2); \ } while (0)

что-то я никак не догоню, зачем функцию "оборачивать" в do {} while?

С уважением, Сергей Борщ

Reply to
Sergey A. Borshch
Loading thread data ...

Hello Sergey.

07 Oct 04 10:44, you wrote to all:

SB> 1) Кому не лень иногда мылом или аськой отвечать на глупые вопросы про SB> заточке uCLinux под мое железо, сборку инструментов и т.д.?

Hаверное, лучше здесь, пока не выходит за рамки топика.

SB> 2) В SB> исходниках Линукса встречается такая конструкция: SB> #define SOME_THING \ SB> do { \ SB> func(arg1,arg2); \ SB> } while (0)

SB> что-то я никак не догоню, зачем функцию "оборачивать" в do {} while?

Где-то я встречал объяснение, счас не помню. Что-то связано с использованием макроса в выражениях. Такой макрос всегда выглядит как один оператор. Hе обращай внимания.

Alexey

Reply to
Alexey Boyko

Привет Sergey!

07 Oct 04 11:44, Sergey A. Borshch писал All:

SB> 1) Кому не лень иногда мылом или аськой отвечать на глупые вопросы про SB> заточке uCLinux под мое железо, сборку инструментов и т.д.?

А можно не мылом? Я тоже как-то хотел его применить, мне было бы интересно послушать. По поводу инструментов типа gcc и binutils могу лишь сказать, что с этим (в отличие от uClinux) никаких проблем у меня никогда не было. Просто делаешь все по инструкции - и все получается.

SB> 2) В SB> исходниках Линукса встречается такая конструкция: #define SB> SOME_THING SB> \ do { \ func(arg1,arg2); \ } while (0)

SB> что-то я никак не догоню, зачем функцию "оборачивать" в do {} while?

Таким образом обычно в языке C оборачивают не функцию, а блок операторов ({}). Дело в том, что после блока операторов в языке C не ставится ";". В результате если ты определишь такой макрос:

#define SMTHNG(x) \ { f1((x) + 5); f2((x) - 10); }

то тебе придется всегда помнить, что SMTHNG() - это не функция, а макрос, и ставить после него ";" не надо, иначе это будет пустой оператор. А вот если этот блок обернуть в do...while(0), то с точки зрения синтаксиса он уже будет неотличим от вызова функции, что гораздо удобнее - не надо забивать себе голову деталями, а потом искать, почему что-то не работает.

Всего наилучшего, [Team PCAD 2000] Алексей М. ... Западно-уральское региональное общество добровольных учредителей.

Reply to
Alex Mogilnikov

Алексей, приветствую!

У меня binutils не собрались - внутренняя ошибка в bison. Debian woodo под VMware. Попытка обновить его (bison) из unstable закончилась крахом системы. Восстанавливаю. Как соберу - пойдут более детальные вопросы.

Мне обычно не везет :-)

Понял. Видимо раньше там было несколько вызовов функций, но в процессе доработок осталась одна. Если бы их было больше одной, ответ был бы очевиден. Но решение красивое. Беру на заметку.

С уважением, Сергей Борщ

Reply to
Sergey A. Borshch
7-Oct-04 17:08 Sergey A. Borshch wrote to Alex Mogilnikov:

SB> Но решение красивое. Беру на заметку.

Кроме устранения проблем с if( cond) SOME_FUNC; // { }; после разворачивания макроса else { }

это дело небезинтересно в таком виде

... do{ // естественно, коментарий что это не цикл ...

if(error1) break; ... ... ... if(errorN) break; ... }while(0)

вместо ... if(!error1) { ... ... ... if(errorN) { ... } } . . }

чтобы и не выехать очень далеко вправо, и не делать отдельную функцию с if(errorK) return; в тех случаях, когда этой функции пришлось бы передавать по ссылке [почти] все локальные переменные текущей функции.

Но я в таком виде while(0) применял может пару раз, очень уж непривычно для себя самого выглядит. А были бы в С локальные функции, так и вообще это не нужно было бы.

wbr,

Reply to
Oleksandr Redchuk

Hello, Alex! You wrote to Sergey A. Borshch on Thu, 07 Oct 2004 14:19:48 +0400:

SB>> что-то я никак не догоню, зачем функцию "оборачивать" в do {} SB>> while?

AM> Таким образом обычно в языке C оборачивают не функцию, а блок AM> операторов ({}). Дело в том, что после блока операторов в языке C не AM> ставится ";".

[...] Не только. Таким образом ещё реализуют "блок finally" :-)). Если нужно в нескольких местах прерывать выполнение вложенного блока, то это можно реализовать через goto, через развесистый if, либо через указанную конструкцию: (1) /* */ if (a) goto label; /* */ if (b) goto label; /* */ if (c) goto label; /* */ label: (2) /* */ if (!a) { /* */ if (!b) { /* */ if (!c) { /* */ } } } /* label: */ (3) do { /* */ if (a) break; /* */ if (b) break; /* */ if (c) break; /* */ } while (0); /* label: */

Кроме того, такая конструкция предоставляет некоторые удобства при использовании отладчика - если "на метке" стоит return, то пр необходимости можно стать именно на него, а не искать все возвраты. Как по мне - это всё сомнительные преимущества (я имею в виду перечисленные мной).

Alexander,Derazhne@adic,kiev,ua (replace commas with dots) Alexander Derazhne

Reply to
Alexander Derazhne

Привет Alexander!

08 Oct 04 17:27, Alexander Derazhne писал Alex Mogilnikov:

AD> Hе только. Таким образом ещё реализуют "блок finally" :-)).

А, да. Я так делал пару раз. Hо, конечно, не в виде макроса. :)

AD> Кроме того, такая конструкция предоставляет некоторые удобства при AD> использовании отладчика - если "на метке" стоит return, то пр AD> необходимости можно стать именно на него, а не искать все возвраты. AD> Как по мне - это всё сомнительные преимущества (я имею в виду AD> перечисленные мной).

Хорошее преимущество - я не люблю нагромождения вложенных if(). По break гораздо понятнее куда идти.

Всего наилучшего, [Team PCAD 2000] Алексей М. ... Крыскас. Потому что крыса вам доверяет.

Reply to
Alex Mogilnikov

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.