Stupid C++ Tricks: Adventures in Assert
От: remark Россия http://www.1024cores.net/
Дата: 27.12.09 18:01
Оценка: 52 (5)
Описываются 5 засадных моментов макросов и не только применительно к написанию собственного макроса ASSERT. Для тех, кто писал собственный ASSERT или логирование с примененением макросов, ничего особого нового не будет, иначе — must read.

http://cnicholson.net/2009/02/stupid-c-tricks-adventures-in-assert/


1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: Stupid C++ Tricks: Adventures in Assert
От: Lorenzo_LAMAS  
Дата: 28.12.09 10:23
Оценка:
Здравствуйте, remark, Вы писали:

R>Описываются 5 засадных моментов макросов и не только применительно к написанию собственного макроса ASSERT. Для тех, кто писал собственный ASSERT или логирование с примененением макросов, ничего особого нового не будет, иначе — must read.


R>http://cnicholson.net/2009/02/stupid-c-tricks-adventures-in-assert/


R>


А что, там где он трюки делает с do while(0) нельзя было просто блок использовать?
Of course, the code must be complete enough to compile and link.
Re: Stupid C++ Tricks: Adventures in Assert
От: Alexander G Украина  
Дата: 28.12.09 10:51
Оценка: +2
Чем-то
do { if (!(x)) f(x); } while(0)
лучше
if (x) {} else f(x)
?
Русский военный корабль идёт ко дну!
Re[2]: Stupid C++ Tricks: Adventures in Assert
От: jazzer Россия Skype: enerjazzer
Дата: 28.12.09 11:00
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>А что, там где он трюки делает с do while(0) нельзя было просто блок использовать?


В ассертах можно, а вот когда тебе нужно какоe-нть логирование (т.е. если ты хочешь писать MY_LOG_MACRO << "test", придется извращаться примерно так:
if ( !log_enabled) ; else
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: Stupid C++ Tricks: Adventures in Assert
От: Lorenzo_LAMAS  
Дата: 28.12.09 11:17
Оценка:
блин, сколько там дальше мути развели в борьбе с предупреждениями компилятора из-за этого while(0). вот это сила!
Of course, the code must be complete enough to compile and link.
Re[4]: Stupid C++ Tricks: Adventures in Assert
От: remark Россия http://www.1024cores.net/
Дата: 28.12.09 11:23
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>блин, сколько там дальше мути развели в борьбе с предупреждениями компилятора из-за этого while(0). вот это сила!


Да, это тоже хорошая тема
Я обычно пишу или "while ((void)0, 0)" или "while (identity(0))", тогда и студия и гцц не ругаются на константые условия и бессмысленные выражения.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[5]: Stupid C++ Tricks: Adventures in Assert
От: Lorenzo_LAMAS  
Дата: 28.12.09 11:27
Оценка:
R>Я обычно пишу или "while ((void)0, 0)" или "while (identity(0))", тогда и студия и гцц не ругаются на константые условия и бессмысленные выражения.
А зачем тебе такие while ?
Of course, the code must be complete enough to compile and link.
Re[6]: Stupid C++ Tricks: Adventures in Assert
От: remark Россия http://www.1024cores.net/
Дата: 28.12.09 11:44
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

R>>Я обычно пишу или "while ((void)0, 0)" или "while (identity(0))", тогда и студия и гцц не ругаются на константые условия и бессмысленные выражения.

L_L>А зачем тебе такие while ?

Обычно это бывает в виде if-ов в шаблонных функциях. Суть одна — как побороть варнинг о константном условии (которое в шаблонной функции не такое уж и константное).


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: Stupid C++ Tricks: Adventures in Assert
От: Кодт Россия  
Дата: 28.12.09 13:40
Оценка: 4 (1)
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>А что, там где он трюки делает с do while(0) нельзя было просто блок использовать?


do-while — это незаконченный стейтмент, после него, как и после выражения, нужно ставить ';'
А блок {...} — законченный стейтмент, лишняя точка с запятой будет воспринята как ещё один, пустой, стейтмент.
Это аукнется в двух местах
— варнинг про пустой стейтмент
— путаница между стейтментами if()... и if()...else...

Если нет нужды в какой-то хитрой логике переходов, то можно привести макрос к выражению
#define UNUSED(expr) ((void)sizeof(expr))

inline void Assert(const char* file, int line, const char* expr, bool cond)
{.....}

#ifdef USE_ASSERTS
#define ASSERT(expr) Assert( __FILE__, __LINE__, #expr, !!(expr) )
#else
#define ASSERT(expr) UNUSED(expr)
#endif

Но тогда отладчик остановится не в коде, а в определении Assert

Против этого можно использовать операторы ветвления и/или следования
#define ASSERT(expr) \
    ( \
        (expr) \
        ? (void)0 /* допущение выполнено - отлично! */ \
        : \
            DebugPrompt(__FILE__,__LINE__,#expr) /* допущение не выполнено - покажем еггог */ \
            ? (void)0 : /* пользователь нажал "пролоджить" - продолжаем */ \
            : (void)DebugBreak() /* точка остановки */ \
    ) \
    //endmacro

Козырно то, что такой ASSERT можно использовать не как стейтмент, но и как выражение в составе других выражений и стейтментов.
Естественно, что он имеет смысл в составе операторов, расставляющих точки останова (?: , && ||)- иначе получим неспецифицированное, а то и неопределённое, поведение.
// правильно
for(x = 0; ASSERT(x>=0&&x<n), x!=n; ++x) { ..... ++x; ..... --x; ..... }

x = (ASSERT(y>0), y  + z)  ; // правильно
x = (ASSERT(y>0), y) + z   ; // сомнительно
x = (ASSERT(y>0), y) + f(y); // неправильно

if((ASSERT(x),true) && f(x)) ..... // правильно
if((ASSERT(x),0   )  + f(x)) ..... // неправильно
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re[2]: Stupid C++ Tricks: Adventures in Assert
От: Basil2 Россия https://starostin.msk.ru
Дата: 28.12.09 14:42
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Чем-то

AG>do { if (!(x)) f(x); } while(0)
AG>лучше
AG> if (x) {} else f(x)
AG>?

А если f(x) несколько?
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[3]: Stupid C++ Tricks: Adventures in Assert
От: Caracrist https://1pwd.org/
Дата: 29.12.09 07:25
Оценка:
Здравствуйте, Basil2, Вы писали:

B>Здравствуйте, Alexander G, Вы писали:


AG>>Чем-то

AG>>do { if (!(x)) f(x); } while(0)
AG>>лучше
AG>> if (x) {} else f(x)
AG>>?

B>А если f(x) несколько?

~~~~~
~lol~~
~~~ Single Password Solution
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.