Assert (обычно) только для отладки
Проблема с "assert" состоит в том, что он обычно находится в отладочных двоичных файлах, и что некоторые разработчики используют их так, как если бы код все еще работал.
Это само по себе не зло, поскольку предполагается, что код интенсивно тестируется, и, следовательно, ошибки, создающие утверждение, обязательно будут обнаружены и удалены.
Но иногда (в большинстве случаев?) Тесты не такие интенсивные, как хотелось бы. Я не буду говорить о старой работе, где нам приходилось кодировать до самой последней минуты ( не спрашивает ... Иногда менеджеры просто ... Гм ... ) ... Что смысл утверждения, которое вы добавляете в код, который будет скомпилирован и передан клиенту как двоичный файл релиза в следующую минуту?
Утверждение в (некоторых) реальных приложениях
В нашей команде нам нужно было что-то, чтобы обнаружить ошибку, и в то же время что-то еще, чтобы обработать ошибку. И нам это понадобилось, возможно, в Release Build.
Assert обнаружит и обработает ошибку только при отладочной сборке.
Поэтому мы добавили вместо этого макрос XXX_ASSERT, а также макрос XXX_RAISE_ERROR.
Макрос XXX_ASSERT будет делать то же самое, что и макрос ASSERT, но он будет построен как в Debug, так и в Release. Его поведение (запись журнала, открытие окна сообщений, ничего не делать и т. Д.) Может контролироваться файлом .INI, а затем он может прервать / закрыть приложение.
Это использовалось как:
bool doSomething(MyObject * p)
{
// If p is NULL, then the app will abort/exit
XXX_ASSERT((p != NULL), "Hey ! p is NULL !") ;
// etc.
}
Макрос XXX_RAISE_ERROR только "регистрирует" ошибку, но не пытается ее обработать. Это означает, что он может записать сообщение в файл и / или открыть MessageBox с сообщением, кнопкой для продолжения и другой для запуска сеанса отладки (согласно конфигурации файла .INI). Это использовалось как:
bool doSomething(MyObject * p)
{
if(p == NULL)
{
// First, XXX_RAISE_ERROR will alert the user as configured in the INI file
// perhaps even offering to open a debug session
XXX_RAISE_ERROR("Hey ! p is NULL !") ;
// here, you can handle the error as you wish
// Than means allocating p, or throwing an exception, or
// returning false, etc.
// Whereas the XXX_ASSERT could simply crash.
}
// etc.
}
Через год после их появления в наших библиотеках используется только XXX_RAISE_ERROR. Конечно, его нельзя использовать в критических по времени частях приложения (для этого у нас есть XXX_RAISE_ERROR_DBG), но везде это хорошо. И тот факт, что можно использовать любую предпочтительную обработку ошибок и то, что ее можно активировать по желанию, либо на компьютере разработчика, либо на тестере, либо даже на пользователе, весьма полезен.