В настоящее время я внедряю систему профилирования в приложение.
У меня есть две функции макроса, которые определены на основе флага компилятора (NDEBUG). Когда NDEBUG не определен, эти две функции (profilingStart и profilingEnd) генерируют отчеты о профилировании, которые показывают время вызова profilingStart и время вызова profilingEnd.
Проблема заключается в возможности возникновения несоответствия, т. е. сценария, когда profilingStart был вызван, а profilingEnd нет (или наоборот). Мой код уже распознает эти ситуации во время выполнения, но было бы предпочтительнее, если бы ошибка возникала во время компиляции из-за этого несоответствия.
Одно из предложений состояло в том, чтобы использовать do{...}while(); конструкция, обеспечивающая правильное сопряжение функций профилирования. Стартовая макрофункция будет содержать do{, а конечный макрос будет содержать }while(). Если один отсутствует, мы получим ошибку во время компиляции. Однако с этим есть некоторые проблемы — вы можете использовать вызовы profilingStart() и profilingEnd() только в начале и в конце профилируемой функции, поскольку их использование внутри функции может повлиять на область действия локальных переменных ( поскольку они могут выйти за рамки из-за вызова do{...}while()).
Еще одна идея, которая у меня была, — просто объявить переменную в функции profilingStart, а затем попытаться изменить содержимое этой переменной в функции profilingEnd. Это предотвращает проблемы с областью видимости и вызовет ошибку компилятора, если переменная никогда не была объявлена. Однако у меня никогда не было бы никакого метода проверки того, что содержимое переменной изменено в конечной функции. Это решает только половину проблемы, так как не проверяет вызов функции profilingEnd.
Любые комментарии приветствуются, как всегда. Заранее спасибо.
РЕДАКТИРОВАТЬ: Может возникнуть некоторая путаница в отношении моих комментариев относительно сферы действия. profilingStart() и profilingEnd() всегда будут вызываться внутри одной и той же функции. Они могут просто не вызываться в самом начале/самом конце функции. Вот пример того, что я имел в виду:
int DoSomething(void)
{
profilingStart();
int a;
DoMath(a);
profilingStop();
return a; // a is out of scope here, as the do{...}while(0) construct has gone out of scope
}
delete
в нужном месте, либо искусственно вводить дополнительную вложенную область видимости для автоматического вызова деструктора в нужное время. - person Oliver Charlesworth   schedule 06.07.2011