реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
Сергей Борщ
сообщение Sep 28 2009, 11:10
Сообщение #16


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(GetSmart @ Sep 28 2009, 13:01) *
Код
    DebugLoop(ShowDebugInfo(); if (I2CMasterState != I2C_SUCCESS));
Код
assert(ShowDebugInfo(), I2CMasterState == I2C_SUCCESS);


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Sep 28 2009, 11:29
Сообщение #17


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(Сергей Борщ @ Sep 28 2009, 17:10) *
Код
assert(ShowDebugInfo(), I2CMasterState == I2C_SUCCESS);

И так допускается использовать assert? Точно так же скомпилится как у меня?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 28 2009, 11:53
Сообщение #18


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(GetSmart @ Sep 28 2009, 14:29) *
И так допускается использовать assert? Точно так же скомпилится как у меня?
Не совсем. Скобки забыл.
Код
extern void ShowDebugInfo();
int a;
void test()
{
    assert((ShowDebugInfo(), a == 2));
}


Errors: none
Warnings: none

Done. 0 error(s), 0 warning(s)


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Sep 28 2009, 11:56
Сообщение #19


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Странно. Я в файле assert.h нашёл слишком примитивный дефайн чтобы такой код к нему подошёл. Там сколько параметров внутрь можно уложить? Эти параметры (ну кроме последнего - условия) точно выполняются как код? Не могли бы Вы выложить дефайн ассерта, который такое "вытворяет".


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 28 2009, 12:01
Сообщение #20


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(GetSmart @ Sep 28 2009, 14:56) *
Не могли бы Вы выложить дефайн ассерта, который такое "вытворяет".
Да любой. Он принимает в качестве параметра выражение, результат которого проверяет на 0. В данном случае я использовал оператор "запятая", объединив в одно выражение и вызов функции и условие, дающее булевый результат.
P.S. Пользуясь случаем: спасибо ReAl, который открыл мне этот интересный оператор своими постами.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Палыч
сообщение Sep 28 2009, 14:01
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Сергей Борщ @ Sep 28 2009, 14:10) *
Код
assert(ShowDebugInfo(), I2CMasterState == I2C_SUCCESS);
Ну, и кому такое надо?
Процедура ShowDebugInfo() будет вызываться вне зависимости от выполнения условия I2CMasterState == I2C_SUCCESS.

Если уж автору исходного топика так хочется что-то (вызов неких действий) добавлять к его исходному действию по условию, то это делается элементарно. Несколько поправил исходный код:
Код
#define DebugLoop(a)    if(a) { DisableIRQ_FIQ(); while (1); }

Если мы желаем при выполнении условия ещё и процедуру ShowDebugInfo() вызвать, то следует записать
Код
DebugLoop(  (I2CMasterState != I2C_SUCCESS) ? (ShowDebugInfo(), TRUE) : FALSE )

где FALSE и TRUE соответственно ноль и не ноль.
Вот Вам и - пожалуйста: перед заходом в бесконечный цикл получите отладочную информацию.
Нечто подобное можно записать и в assert, однако аргумент его используется не только для проверки условия, но и для формирования строки вывода (не смертельно, конечно, но - некрасиво вывод будет смотреться).

P.S. В assert , конечно, вызов дополнительной процедуры нужно перенести к FALSE.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Sep 28 2009, 14:29
Сообщение #22


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(GetSmart @ Sep 28 2009, 11:58) *
По поводу do {} while(0) в дефайнах. Кто-нить может объяснить чем это лучше простого {} ???

Не-не. Лучше for(){} навернуть функционалом. Чтоб можно было не бояться встретить побочные эффекты от break или return при вызове какого-либо хитрого макроса.
Кстати, проблему с обертками для обработчиков (sub lr,lr,#4 ) тоже можно решать с помощью for()
Go to the top of the page
 
+Quote Post
ReAl
сообщение Sep 28 2009, 15:35
Сообщение #23


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(Палыч @ Sep 28 2009, 17:01) *
Ну, и кому такое надо?
Процедура ShowDebugInfo() будет вызываться вне зависимости от выполнения условия I2CMasterState == I2C_SUCCESS.
...
P.S. В assert , конечно, вызов дополнительной процедуры нужно перенести к FALSE.

Или так
Код
assert( I2CMasterState == I2C_SUCCESS || (ShowDebugInfo(), 0) );
DebugLoop(  I2CMasterState != I2C_SUCCESS  && (ShowDebugInfo(), TRUE) );


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 28 2009, 15:37
Сообщение #24


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Палыч @ Sep 28 2009, 17:01) *
Ну, и кому такое надо?
Процедура ShowDebugInfo() будет вызываться вне зависимости от выполнения условия I2CMasterState == I2C_SUCCESS.
GetSmartу. Его макрос делал то же самое. А в остальном вы все правильно расписали.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
ReAl
сообщение Sep 28 2009, 15:55
Сообщение #25


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(_Pasha @ Sep 28 2009, 17:29) *
Не-не. Лучше for(){} навернуть функционалом. Чтоб можно было не бояться встретить побочные эффекты от break или return при вызове какого-либо хитрого макроса.
Дык вроде break одинаково отрабатывает что из того цикла, что из другого. Это по continue в for хвостовой оператор выполнится.

do { } while(0) для другого сделан, чтобы макрос можно было ставить в любое место и привычно писать после него ';', тут уже писали
Код
// примитив, но для общности изложения
#define foo()  op1; op2;

if(a)
    foo(); // в тихую op2 выполняется всегда

if(a)
   foo();
else        // syntax error
   op3;


Код
#define foo()  { op1; op2; }

if(a)
    foo(); // "висящий" ';' , но это не страшно

if(a)
   foo();
else       // syntax error
   op3;

Код
#define foo()  for(int i = 0; i < 1; ++i) { op1; op2; }

if(a)
    foo(); // "висящий" ';' , но это не страшно

if(a)
   foo();
else       // syntax error
   op3;


Код
#define foo()  do { op1; op2; } while(0)

if(a)
    foo(); // OK

if(a)
   foo();
else       // OK
   op3;


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Sep 28 2009, 16:55
Сообщение #26


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(ReAl @ Sep 28 2009, 18:55) *
Дык вроде break одинаково отрабатывает что из того цикла, что из другого. Это по continue в for хвостовой оператор выполнится.

Это я про ATOMIC_BLOCK() из winavr - там хвостовая часть с атрибутом cleanup и связана с объявленной локальной переменной, поэтому выполнится всегда, даже при break/return.

А так, вообще - про ; подозревал smile.gif
Ну, и использовать break/continue в других случаях - опять же, создавая макроопределениями единый смысловой контекст - тоже неплохо.


Цитата(GetSmart @ Sep 28 2009, 12:51) *
Например выполнить какие-нить предворительные действия перед зависанием, которые в режиме Release не будут даже компилироваться, а в Debug будут стоять. Как частный случай этого - оператор if

Код
#define DEBUGLEVEL 1

#define DEBUG_LOOP(level, assertion) do{if(( level <= DEBUGLEVEL) && (assertion)) for(;;);}while(0)

Я правильно понял? level как константное выр-е, так и динамическим может быть. В последнем случае, конечно, надо позаботиться о значении DEBUGLEVEL, чтобы все отфильтровывалось.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Sep 28 2009, 17:33
Сообщение #27


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(Сергей Борщ @ Sep 28 2009, 21:37) *
GetSmartу. Его макрос делал то же самое. А в остальном вы все правильно расписали.

Ну не знал я про assert. Вот, изобрёл велосипед, а люди вокруг запинали творческую личность biggrin.gif Средневековье какое-то.

Знаю, что есть недостаток моего дефайна в том, что он не "ATOMIC", то есть нельзя перед ним написать if (...), хотя условие должно быть внутри (так и было задумано), но иногда из-за этого можно ненароком встать на грабли, если например мой дефайн с процедурой внутри написать сразу после else. Пришлось бы писать примерно так:
Код
if (...)  ++I2CMasterState;
else { DebugLoop(ShowDebugInfo(); if  (I2CMasterState != I2C_SUCCESS)); }


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
sysel
сообщение Sep 29 2009, 04:39
Сообщение #28


Знающий
****

Группа: Свой
Сообщений: 601
Регистрация: 3-07-07
Пользователь №: 28 852



Ерундой маетесь, товарищи.
Подобные навороты резко снижают читабельность кода.
Вот влезете Вы в свой код годика так через 3 и будете репу чесать у каждой строки, которая Вам сейчас кажется гениальной.
А если кто-то посторонний влезет - вообще труба...
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 8th July 2025 - 23:11
Рейтинг@Mail.ru


Страница сгенерированна за 0.01499 секунд с 7
ELECTRONIX ©2004-2016