Skip to main content
gamedev.net
🔒 Locked

Asserts

Started by Dolf 12 replies 1.3k views
Original Post
Dolf
Dolf
Hi, I think since I upgraded to microsoft visual studio 2008, a

assert( 0 );


just closes the application. How can I get that big fat error message back? Does anyone else have that problem or did I ever click some windows option that makes those messages not pop up anymore? Cheers,
bzroom
bzroom
Write your own version of assert, inside it should call one of these
http://msdn.microsoft.com/en-us/library/8hyw4sy7(VS.71).aspx on windows platforms.

I also like to rewrite assert so that i can control the way it [does or doesnt] get compiled out in release builds. And also because i like to have a description parameter.

Assert(p != NULL, "p was null"); //gets compiled out in release builds
AssertPerminant(p->Validate(), "p is invalid"); //never gets compiled out

(i'm not saying those are good times to use each function, they are just an example, in lots of cases you dont want the assert removed [why remove error checking?] so maybe you want the default one [Assert] to be the one not compiled out, and AssertDebug for the one that Does get compiled out, but it's totally up to you.)
hallucinogenic
hallucinogenic
Quote:
Original post by bzroom
I also like to rewrite assert so that i can control the way it [does or doesnt] get compiled out in release builds. And also because i like to have a description parameter.

Assert(p != NULL, "p was null"); //gets compiled out in release builds
AssertPerminant(p->Validate(), "p is invalid"); //never gets compiled out

(i'm not saying those are good times to use each function, they are just an example, in lots of cases you dont want the assert removed [why remove error checking?] so maybe you want the default one [Assert] to be the one not compiled out, and AssertDebug for the one that Does get compiled out, but it's totally up to you.)


Asserts are not meant to be (nor are they) error handling. They are meant to state and enforce the assumptions of a piece of code. So, unless your release build assert simply logs the fact that the assert failed, you are, in effect, preventing error handling from being possible.
bzroom
bzroom
You're right, but I didn't say error handling, I said error checking.
Mostly checking assumptions like you said.

I understand how you could say it "prevents" error handling since it stops the code. But if that code is going to do unpredictable things (because error handling was not implemented, and the function was only error checked with asserts) then the code should stop immediately and log the proper message, no matter what build it is.
Dolf
Dolf
I'll just create my own assert which consists of a windows message box to tell me the error with __LINE__ and __FILE__.

But I'm wondering why my normal asserts won't work.
Fruny
Fruny
Quote:
Original post by Dolf
But I'm wondering why my normal asserts won't work.


If they close the application, they work. There is nothing that says they have to trigger a pop-up.

Fire your application in a console window, or run your program in a manner that does not close that window when the program ends and check if any traces are output there.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Dolf
Dolf
Ok thanks fruny, I'll try that.

I'll still be using this as an alternative though:

#ifndef _H_ASSERT#define _H_ASSERT#ifndef NDEBUG#include "stdio.h"#include "windows.h"#define assert( expression, message )\ 	if ( expression == false )   \ 	{                            \ 		char caption[256];   \ 		sprintf_s( caption, "File: %s, \nLine: %i", __FILE__, __LINE__ ); \ 		MessageBox( 0, caption, message, 0 ); 		exit( 0 );	     	}#endif#endif


Edit: these source boxes remove my \ at the end of each line

Edit by Fruny: formatting.
Dolf
Dolf
Ahhhh, I had Multi-threaded (/MT) instead of Multi-threaded Debug (/MTd) in my compiler options.
Fruny
Fruny
Also, keep in mind that a zero exit code indicates a program that terminated successfully. Condider using a non-zero exit code, or the abort or std::terminate functions.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
nullsquared
nullsquared
Also, your assert() will mess up conditionals:
// just a quick exampleif (pointSelected)    assert(deletePoint()); // make sure deletePoint() returns > 0else    selectPoint();

Can you spot the error?
Dolf
Dolf
Ah I see, the else will be the wrong if statement. I'll add some { and } around it then, thanks.
OrangyTang
OrangyTang
Quote:
Original post by Dolf
I don't see the mistake?

When expanded, the 'else' in your code with pair with the 'if' inside of the assert, instead of the 'if' above the assert.

It's generally a good idea to wrap your macros in
do { } while(0)
to prevent these kind of problems.
Dolf
Dolf
Haha ye, I saw it. I first created it as a function but that didn't work with the __LINE__ / __FILE__. I wasn't careful enough.

Edit: do { } while(0) ? why not just the { and } ?
OrangyTang
OrangyTang
Using 'do/while' forces the whole macro to be treated as a single statement, which just using surrounding {} doesn't do.

It also means that you're required to put the finishing ';' after it, eg:

if (something)
MACRO(cond);

The do/while variant of MACRO requires the semicolon. Just adding {} in the macro doesn't do this and will cause odd behaviour in the above case.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.