|
|
| create_bitmap() problem. |
|
spunit262
Member #5,545
February 2005
|
The docs never said not to pass 0,0 to create_bitmap, so your point is mutt. |
|
Carrus85
Member #2,633
August 2002
|
It is kindof a trade off... you can have the "contractual agreements" enforced all of the time, or only enforce them under development (to ensure proper execution). For the most part, the latter is the method that makes the most sense, because errors like this shouldn't creep up in a release-mode project (thus, you should compile your program in debug mode until all assertions are met (pre and post conditions)), then you should be safe to compile in release mode. Unless of course this is a very security critical application, than keeping the pre and post condition checking in release mode is prudent. Since most games are performance critcal, not security critical, it makes sense that these conditions are only checked during development, not continuously during runtime. At least that is how I learned it in College CNS classes...
|
|
Thomas Harte
Member #33
April 2000
|
Quote: The docs never said not to pass 0,0 to create_bitmap, so your point is mutt. They also don't say not to pass a casted BITMAP pointer to play_sample. So the docs not saying something is not enough to say that "your point is mutt". At least is isn't based on my guess at what you mean by that, i.e. that mutt means void. [My site] [Tetrominoes] |
|
Richard Phipps
Member #1,632
November 2001
|
For speed critical functions (say the getpixel, putpixel type ones) then I agree that the checking may be a concern. But I don't know of any programmer who would do a create and destroy_bitmap call in a inner loop. Just the malloc alone must take much more time than the double check on the width and height. For that reason, I would add the checks. |
|
spunit262
Member #5,545
February 2005
|
Quote: They also don't say not to pass a casted BITMAP pointer to play_sample. So the docs not saying something is not enough to say that "your point is mutt". At least is isn't based on my guess at what you mean by that, i.e. that mutt means void. No one with a brain would do that, but there are zero size arrays so who's to say you can't make a zero size bitmap. |
|
HoHo
Member #4,534
April 2004
|
Quote: The docs never said not to pass 0,0 to create_bitmap, so your point is mutt. You are reading the wrong documantation As was reported earlier, docs do say that 0x0 bitmap is not allowed: That means height must be 1, 2, 3, ..., a_big_number and width must be in 0, 1, 2, ..., a_big_number. __________ |
|
Thomas Harte
Member #33
April 2000
|
Quote:
No one with a brain would do that, but there are zero size arrays so who's to say you can't make a zero size bitmap. I'll use my brain when you start saying what you mean. Your sentence was "The docs never said not to pass 0,0 to create_bitmap, so your point is mutt." which implies to me merely that points are 'mutt' if they rely on people assuming things that aren't in the docs. I suggest you try a sentence such as "This isn't obviously going to cause a problem and the docs never said not to pass 0,0 to create_bitmap, so your point is void." should you ever want to make the same point again. [My site] [Tetrominoes] |
|
Bob
Free Market Evangelist
September 2000
|
Quote: which implies to me merely that points are 'mutt' I think he meant 'moot' -- |
|
spunit262
Member #5,545
February 2005
|
That's to long a stentes for me. I like to be short and to the point, witch sometime makes me sound rude. Ok. If your going to be overly picky end it with </jk>, or some thing like that. |
|
ReyBrujo
Moderator
January 2001
|
In the past, passing a NULL pointer to a %s argument in a printf call would crash the application. Nowadays I think it prints (null) instead. I would think processor speed is so good that using some checks inside the functions are not a big performance hit. However, programmers become lazy and stop checking because it is the library task. At work we had this heated argument. In one side, everytime a friend got a NULL parameter which was not logically allowed, he would throw an error that would end crashing the application. In the other side, friends prefer handling the NULL pointer, in example, returning the function immediately, and dismissing the call. And the discussion was basically, the clients get pissed off because we make the application crash in order to get a full home made trackback and spot which check failed (isolating the problem and fixing in either the code or the client database), but if we didn't, we never learn the client's database had this problem which was carried over during months until it became so critical the database would take several weeks of intense working just to fix it. Since Allegro is an amateur-for-amateur game programming, I believe checks are good. Allegro is usually the first or second game library a programmer would try, and it should be as newbie friendly as possible. If that includes checking for invalid parameters, so be it. -- |
|
Richard Phipps
Member #1,632
November 2001
|
Couldn't you pass an error message to an internal string, set a flag, return without crashing and then in a seperate thread check for an error in the background and print out the full error details? Or call a function pointer (if not NULL) from within each function if an error occured and passing it the error text. That would let people use custom error reporting functions.. |
|
ReyBrujo
Moderator
January 2001
|
Maybe in debug mode. But most will just want the application to finish with the error message, just as most people want the default X behaviour is to close the window, as much asking if you really want to. -- |
|
Kitty Cat
Member #2,815
October 2002
|
Quote: In the past, passing a NULL pointer to a %s argument in a printf call would crash the application. Nowadays I think it prints (null) instead. I think it depends on the optimization settings and the compiler. I rememberfor one game I was making, DJGPP would print "(null)", but under Linux, with a newer GCC, it would crash. -- |
|
Thomas Harte
Member #33
April 2000
|
Quote: I think he meant 'moot' In which case I had entirely the wrong idea about what he was saying and all misunderstandings are entirely my fault. Apologies all round! Obviously there is a gulf of difference between a void point (one which is clearly invalid) and a moot one (one which is sufficiently borderline to be arguable either way). Quote: Since Allegro is an amateur-for-amateur game programming, I believe checks are good. Allegro is usually the first or second game library a programmer would try, and it should be as newbie friendly as possible. If that includes checking for invalid parameters, so be it. I agree with this, especially since there can't be a reasonable developer on the planet trying to get decent performance out of any loop which involves a malloc? [My site] [Tetrominoes] |
|
A J
Member #3,025
December 2002
|
given create_bitmap() is not speed critical, is there any harm in adding the check. can we set a errno number for this condition, so the user after receiving a NULL ptr can check it to find out why. ___________________________ |
|
Kitty Cat
Member #2,815
October 2002
|
Quote: given create_bitmap() is not speed critical, is there any harm in adding the check Personally, I wouldn't mind a check for both to be > 0, but I really would like those assert's to remain. So, like:
-- |
|
Evert
Member #794
November 2000
|
Just a quick round of answers before I roll into bed. These are my personal views after skimming through the thread with a throbbing headache and a sore throat so I apologise beforehand if I insult anyone. The docs clearly say that you cannot create a 0x0 size bitmap. If you try to do so anyway, the consequences are for you. Perhaps it can be argued that destroy_bitmap() should not crash or create_bitmap() should return NULL instead, but since the user code is in error in this case I personally don't think this is proper behavior for the library. Changing this in the way suggested will make code run normally (without errors) in release mode and it will cause a crash in debug mode. This is not acceptable. Allegro's policy is to do pedantic sanity checks only in debug mode and at least for 4.2, this is not going to change. How failures and problems should be dealt with after 4.2 is a different discussion. No, passing NULL to a %s format specifier in printf() is not ok. If the result is the insertion of the string (null) this is non-standard behavior (granted, it's non-standard behavior used by many compilers, but it's still non-standard). We've had a few patches to Allegro that solved crashes because the library assumed it did. |
|
Kitty Cat
Member #2,815
October 2002
|
Quote: Perhaps it can be argued that destroy_bitmap() should not crash or create_bitmap() should return NULL instead, but since the user code is in error in this case I personally don't think this is proper behavior for the library.
I'm not totally sure if returning an invalid bitmap should be allowed either, though. IMO, it should either return a bitmap with a NULL dat field, or a NULL struct. Neither should cause problems when passing the result to destroy_bitmap, so this would always work: -- |
|
A J
Member #3,025
December 2002
|
Quote: will make code run normally (without errors) in release mode and it will cause a crash in debug mode. This is not acceptable. kittycats suggestion, of leaving the asserts in but including the check after the asserts, would allow debug & release modes to act consistantly, whilst offering warnings to users in debug mode via the asserts. Should all non-speed critical functions check input parameters for sanity ? [edit] to me the "or" word implies the 1st half of the sentence is the opposite to the end, the end being NULL if not created, therefore the start of the sentence says non-NULL if created. So if a bitmap is created successfully (non-NULL ptr), then it should be able to feed that ptr to destroy_bitmap() without a hard crash. ___________________________ |
|
GullRaDriel
Member #3,861
September 2003
|
you all should know what you code. create_bitmap crash if size is 0x0 ? so don't use a 0x0 size. it is evil to think that library develloper must have a thought to everything. error checking is also the job of the user of the lib. Excuse me, but if you're too dumb to not do yourself some check, you 'll loose a lot of time on non-initialised pointer & else when debugging. Aren't you checking , when doing A=1/B , if B isn't zero ? i hope you do. "Code is like shit - it only smells if it is not yours" |
|
Kitty Cat
Member #2,815
October 2002
|
BTW Quote: Changing this in the way suggested will make code run normally (without errors) in release mode and it will cause a crash in debug mode. This is not acceptable. Returning a NULL bitmap is considered an error (it's not wanted behavior).. means something went wrong and the bitmap couldn't be made. I can't think of a situation where a returned NULL bitmap doesn't indicate a problem. However, by returning NULL in release, it allows the program to handle it more gracefully, while in debug mode the ASSERT's would throw the problem to the debugger. EDIT: Quote: create_bitmap crash if size is 0x0 ? so don't use a 0x0 size. create_bitmap doesn't crash. It crashes when you try to call destroy_bitmap on a 0-sized bitmap. And no one's saying 0x0 bitmaps should be allowed.. we're just determining what the best method of dealing with it would be (return an error with a NULL bitmap so the program can handle the problem, or let it create an invalid bitmap that will crash the program later). Quote: it is evil to think that library develloper must have a thought to everything.
Which is why we're bringing it up, since someone else found it. Quote: error checking is also the job of the user of the lib. What should be checked by the user, and what should be checked by the lib? In non-speed-critical functions, such as this, it should be safe to assume the lib will make sure it won't cause a situation to allow itself to crash later. Quote: Excuse me, but if you're too dumb to not do yourself some check, you 'll loose a lot of time on non-initialised pointer & else when debugging. When your projects get larger and larger, it becomes increasingly harder to keep track of everything. Situations that couldn't happen before could happen now, but you wouldn't realize it until it's too late. For non-speed critical functions, it'd be best to let the lib check and save on having all of its users program the exact same safety checks (or not, and risk questions of why the program crashes, and time wasting hunting uncaught problems). Quote: Aren't you checking , when doing A=1/B , if B isn't zero ? i hope you do. Not in situations where I can't conceive B being 0. And if it is, it'll crash, I'll debug, and catch the problem. Something like this would be easy since it crashes right where the problem is. But with a 0-sized bitmap, you may not get a crash until the program closes, even if the problem is when the program begins. -- |
|
Elias
Member #358
May 2000
|
I agree, we could change this for create_bitmap, especially since it would be consistent to load_bitmap to return NULL in case it fails. But in general, what is a speed critical function? If I do: bmp = create_bitmap(w, h); line(bmp, 0, 0, 10, 10, 0); Then it will crash now in line 2. line certainly isn't a speed critical function (adding a check for NULL takes no time at all compared to all the checks it already has to do). So, this really opens a can of worms.. I'd say, we should leave the ASSERTs in 4.2.0, they are a perfectly good way of error checking. After 4.2.0, we could implement something like OpenGL, where every function returns an error code. Or maybe even better, provide a global error callback which is called for errors (in which you can e.g. raise an exception - or in C you could use longjmp to jump to a user exception handler). -- |
|
GullRaDriel
Member #3,861
September 2003
|
it is speed critical if you do this: while(do_draw){ line(...) } an error check will slow the draw loop. "Code is like shit - it only smells if it is not yours" |
|
Elias
Member #358
May 2000
|
Not really, just because you use it in a loop doesn't make it speed critical, else create_bitmap would be as well: while(do_draw){ bmp = create_bitmap(...); line(bmp, ...); blit(..., bmp, ...); destroy_bitmap(bmp); }
-- |
|
ReyBrujo
Moderator
January 2001
|
create_bitmap is so slow that adding a check there is depreciable. -- |
|
|
|