|
paladin_t
|
 |
« on: July 10, 2012, 05:27:23 PM » |
|
We are making a game editor. The story is the technique director don't allow us to use "assert", unbelievable he even doesn't know it only pops an assertion dialog in debug mode, unbelievable he even doesn't know it an insurance for developers to solve problems which must be solved during dev period, unbelievable he even doesn't allow me to add assertions every time and tells me to use "if(shit != null) { FuckTheShit(); }" style guard in every case... Oh, his only reason is "The failure dialog box is annoying to end users"...
|
|
|
|
|
Logged
|
|
|
|
|
gf11221
Guest
|
 |
« Reply #1 on: July 10, 2012, 05:40:47 PM » |
|
You must check again the source, did he used an open-source editor engine? If so, the engine might not compatible to the game or the codes he applied or changed has some problems. If he did it, why he couldn't even fix it by himself? That was too mysterious 
|
|
|
|
|
Logged
|
|
|
|
|
paladin_t
|
 |
« Reply #2 on: July 10, 2012, 05:50:26 PM » |
|
No 3rd party engine, totally internal code. I don't want to be vexing. The biggest problem was it seems he didn't know assertion failure dialog wouldn't appear in release mode. I think I need to talk with him.
|
|
|
|
|
Logged
|
|
|
|
Ludophonic
Level 1
|
 |
« Reply #3 on: July 10, 2012, 07:57:58 PM » |
|
Ah, asserts. Nothing like grinding a twenty person team to a halt because some idiot programmer decided that using a fixed sized array for something would be fine because they added an overflow check. Someone checks in an additional piece of data and boom! everyone who has the misfortune of syncing to the repository gets to sit around on their hands while waiting for it to be fixed.
Damn great way to train people to never sync unless absolutely necessary, even avoiding it when checking in themselves if they can.
If your tech director has had similar experiences that's probably where his aversion to them comes from.
The way around this is to have your asserts pop up a dialog with the option to either - (i) crash right there, (ii) ignore the assert a single time and continue, or (iii) ignore all further instances of the particular assert.
The other problem with asserts is that they can cause hard to find bugs when someone does work within the assert. Everything works fine in debug but you get crashes in release. Make sure you write your macro so that any function call or whatever within an assert will get called even in release in case someone does assert( LoadAssetGameCantDoWithout() ); Also check to see that it's not capable of causing dangling else's and such.
If you can show your tech director that you've taken care of the potential problems he may be more open to using them. But if he doesn't like them because he thinks they just lead to lazy coding—which is another common problem—you might have an uphill battle.
(I very rarely use asserts myself, but the above can make them tolerable)
|
|
|
|
« Last Edit: July 10, 2012, 08:05:22 PM by Ludophonic »
|
Logged
|
|
|
|
|
Evan Balster
|
 |
« Reply #4 on: July 10, 2012, 08:06:56 PM » |
|
After three years working on a system I've begun to feel like using assert-style semantics was a bad idea. If they only trigger in debug mode, then my debug mode might stop the program prior to some condition which causes a crash, thereby exposing the release mode to that issue. If the assert takes effect either way, there's a very nasty inescapable error dialog that might pop up in release mode.
I've been tempted to switch to structured exception handling but another viable approach might be implementing a "recover" option wherever possible.
|
|
|
|
|
Logged
|
|
|
|
|
xgalaxy
|
 |
« Reply #5 on: July 10, 2012, 08:40:31 PM » |
|
If you use asserts correctly they solve more problems than they potentially create. Riddling code with if checks that early out or modify state, when an assert would have been better, only serves to hide bugs, not solve them.
My assert macros bring up a dialog when they are triggered which state the file, line, callstack, and the values of any variables involved in the condition being checked. I have two categories of asserts: warnings and fatal errors - both bring up a dialog but only warnings can be dismissed and the program resumed. They both trigger a debug break so I can attach to process right there if not already running in one.
|
|
|
|
« Last Edit: July 10, 2012, 08:47:00 PM by xgalaxy »
|
Logged
|
|
|
|
|
Nix
|
 |
« Reply #6 on: July 10, 2012, 08:48:01 PM » |
|
I use asserts in situations which my planning should have made impossible. For example, I used an assert in this function: gint layer_node_removed (gpointer host, GeglEditor* editor, gint node_id) { GeglEditorLayer* self = (GeglEditorLayer*)host; GeglNode* node = NULL; GSList* pair = self->pairs;
for(;pair != NULL; pair = pair->next) { node_id_pair* data = pair->data; if(data->id == node_id) { node = data->node; break; } }
g_assert(node != NULL);
gegl_node_disconnect_all_pads(node); gegl_node_remove_child(self->gegl, node); }
(I know I could do this more efficiently) This is for a GUI application, and by design this function should never be called with an id which isn't associated with a GeglNode*. I would be silly to use exception handling, because it should never happen. If this assert fails, I know there is something horribly wrong elsewhere in my code. I have no fallback in this situation, and I have to find the problem. I could have something like if(!node) return; and ignore it altogether, but that would be ignoring an issue which indicates broken code somewhere else in my program. Asserts are like little sanity checks that what we planned is working properly. Exceptions should be used as tools for program flow, and not as a response to unexpected errors. A good use of exceptions would be if a file reading function throws an exception when trying to read a config file, then the program has the opportunity to create a new config file and prompt the user for graphics settings. Or if we had a parsing function, it could possibly throw one of a number of exceptions indicating the type of parsing error which an exception handler could then share with the user in an easily-readable format.
|
|
|
|
|
Logged
|
|
|
|
|
paladin_t
|
 |
« Reply #7 on: July 10, 2012, 08:58:41 PM » |
|
If I was making a midware, I'd like to avoid assertions in API functions; but I prefer to use assertions for a full product, especially with a strong typing and strict checking language like C++. I don't like exception handling, IMO assertion tells me when I met something I had to handle, or that might be a logic fault, an exception just hides and delays it. We often check whether the data (or something else) is valid before using it, sometimes I'd ask myself: why invalid data could passed to this function? If it shouldn't then I'd add an assertion right there.
|
|
|
|
|
Logged
|
|
|
|
|
Ashaman73
|
 |
« Reply #8 on: July 10, 2012, 10:59:56 PM » |
|
I don't want to justify the ban of asserts (I use it myself extensivly in my game), but there're some disadvantages, most importantly the problem, that the behaviour in debug-mode (developer mode) is different from the one in release-mode (user mode). Best example, as already stated, is assert(doSomethingImportant()); . This could result in endless discussion: artist: 'hey, the editor crashed from time to time (no assert), don't know why'  developer: 'nah, I tested it (in debug mode) all the time (using only a single test path for 25 sec) , try to figure out when it happens. '  artist: ' ok, it crashed right after I got a cup of coffee, seems to be the coffee-machine then'  developer: ' ehmm..no... I will give you a debug build'  artist: ' sry, I can't work with it, it is soooo slow ...'  (half day later, 5 artist are standing around one artist to provoke the bug by drinking lot of coffee):  artist: ' huh... everything works fine now.. need to hold my deadline, switching back to release build'  (3 mins later) artist: ' it crashed again...'  The reason: some former rookie coder inserted an important function call inside an assert. In release mode this call was missed and resulting in a crash in an other part of the code. Yes, pro coders knows what to do (most of the time  ), but you can't expect to have veterans on a single application all the time.
|
|
|
|
|
Logged
|
|
|
|
|
ThemsAllTook
|
 |
« Reply #9 on: July 11, 2012, 04:30:51 AM » |
|
Asserts conceptually bug me, because I really don't like having to catch errors at runtime. I write my code to first catch as many problems as possible during compilation (rigorous use of const, gcc __attribute__s for sentinels on functions, etc.), and for anything that can't be caught there, I try to cover it with a unit test, which runs automatically every compile. The remaining bits of code that can't be fully checked by either of those end up being very small, so errors are minimized and relatively easy to find. If something does manage to go wrong at runtime, I want it to either crash noisily with a segfault (in all build modes) or recover fully.
|
|
|
|
|
Logged
|
|
|
|
|
Nix
|
 |
« Reply #10 on: July 11, 2012, 04:43:56 AM » |
|
If something does manage to go wrong at runtime, I want it to either crash noisily with a segfault (in all build modes) or recover fully.
Asserts are great because they crash noisily and tell you exactly what was wrong. If you wait for a segfault, you might miss the source of the issue and then be scratching your head when the program finally decides to crash.
|
|
|
|
|
Logged
|
|
|
|
Sir Wolf
Level 0

A wolf cub growing up
|
 |
« Reply #11 on: July 22, 2012, 05:11:36 AM » |
|
I use asserts in situations which my planning should have made impossible.
--
Asserts are like little sanity checks that what we planned is working properly. Exceptions should be used as tools for program flow, and not as a response to unexpected errors. A good use of exceptions would be if a file reading function throws an exception when trying to read a config file, then the program has the opportunity to create a new config file and prompt the user for graphics settings. Or if we had a parsing function, it could possibly throw one of a number of exceptions indicating the type of parsing error which an exception handler could then share with the user in an easily-readable format. This is pretty much my angle on the issue too. How I learned it was that asserts are for programming errors - a function parameter being null in a function I know should never be called with a null parameter tells me that there is an error I need to fix somewhere in the code. Exceptions I use for conditions I as a programmer can't do anything about beforehand - for instance missing or corrupted data files.
|
|
|
|
|
Logged
|
"We don't stop playing because we grow old; we grow old because we stop playing." -George Bernard Shawn
|
|
|
|
Orz
|
 |
« Reply #12 on: July 23, 2012, 10:42:41 AM » |
|
This is a really interesting discussion. I just had this same argument with one of my co-workers, who uses assertions all the time while I avoid them.
We came to pretty much the same consensus that I see in this thread. Assertions are easy to misuse, if you use them to avoid learning about how your code works and sweep errors under the carpet. But they're invaluable for debugging, where, by definition, you don't know how your code works, and no elaborate chain of if-statements will tell you what went wrong.
Glad to see someone else is questioning the conventional wisdom though...
|
|
|
|
|
Logged
|
|
|
|
|
achild
|
 |
« Reply #13 on: July 23, 2012, 12:57:37 PM » |
|
For me, ASSERT(x) just means "At this point, x should be true, no matter what." And since they tend to be debug-mode only, they are pretty plainly a first-line of defense for programmers. In the example about the static array - the assert was good!! The problem was the static array, not the assert. Removing the assert doesn't fix the issue heheh.
And... of course they can be misused. What can't?
With that said, one of course has to carefully pick and choose which features of a complex programming language (like c++) to use and which ones to stay away from. One software house might avoid using new at all costs. Another, asserts. Another, multiple-inheritance.
I don't think this is really a right or wrong thing.
|
|
|
|
|
Logged
|
|
|
|
|
Muz
|
 |
« Reply #14 on: July 23, 2012, 05:30:25 PM » |
|
You can code just fine without assertions. Not really a smart move, but there have been far worse barriers to good programming. And assertions are not something to religiously stick to.
The failure crashes shouldn't be an issue. If you don't like the mess, just keep them while you're in beta.
Not really that much of an issue to do 'if.. then..' kind of guards, which dump errors into a log. You can probably just make a function that handles this, and customize it to crash noisily or quietly whenever needed.
|
|
|
|
|
Logged
|
|
|
|
|