Какой смысл делать while (0), когда мы определяем макрос? [дубликат]




Возможные Дубликаты:
операторы Do-While и if-else в макросах C / C++






Я читаю ядро linux, и я нашел много макросов, как это:



#define INIT_LIST_HEAD(ptr) do { 
(ptr)->next = (ptr); (ptr)->prev = (ptr);
} while (0)


почему они используют это, а не просто определить его в {}?

604   2  

2 ответов:

вы можете следовать за ним с точкой с запятой и сделать его похожим на функцию. Он также работает с предложениями if/else должным образом.

без while(0), ваш код выше не будет работать с

if (doit) 
   INIT_LIST_HEAD(x);
 else 
   displayError(x);

так как точка с запятой после макроса "съест" предложение else, и вышеизложенное даже не будет компилироваться.

Это позволяет группировать несколько операторов в один макрос.

Предположим, вы сделали что-то вроде:

if (foo) 
    INIT_LIST_HEAD(bar);

Если макрос был определен без герметизации не ... } пока (0); приведенный выше код будет увеличен до

if (foo)
    (bar)->next = (bar);
    (bar)->prev = (bar);

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

Edit: дальнейшее объяснение на http://c-faq.com/cpp/multistmt.html и http://developer.apple.com/documentation/DeveloperTools/gcc-4.0.1/cpp/Swallowing-the-Semicolon.html#Swallowing-the-Semicolon

Comments

    Ничего не найдено.