MESSAGE
DATE | 2004-09-10 |
FROM | Billy
|
SUBJECT | Re: [hangout] Re: two dimensional arrays passed to functions
|
On Fri, Sep 10, 2004 at 12:50:05PM -0400, Ruben Safir Secretary NYLXS wrote: > > > Functions should be kept clean enough that it isn't a problem. So > > abusing goto is very bad, but so is abusing any other feature. I > > know that when I use it, it's as a sort of last resort when the > > alternatives would be worse (read: more bug-prone). > > > > Like longjump and short jump for errors?
You're thinking of setjmp/longjmp ? Those are hard to deal with, but they can be used to implement a primitive exception throwing facility.
> >> In addition, there is always signals, which is how I originally > >> handled errors. The thing is here, the 'error' is not necessarily > >> an error. It could be a normal response from the database, like an > >> attempt to insert already entered data on a unique key. In which > >> case, I want to switch over and do an UPDATE instead. > > > > Sound thinking. You're talking about gtk signals or Unix signals? > > I meant unix signals, singnals.h I think in the C library. Also, > consider GTK, in their obsession to force an Object-like notation onto > everything, one of the benifits is that instead of capturing the whole > of a structured program in if statements, you should be able to emit a > GTk signal to the top level window, or carry the error handling up the > tree, which already exists, without the need for break break break.
Right, but you have to be careful about carelessly exiting a function in which you've allocated resources.
f() { char *p = malloc(1); if( risky_function() == SCREWUP ){ /* congratulations! * You've got a memory leak! */ return; } free(p); return; }
or: f() { int fd = open("/tmp/foo", O_RDONLY); if( risky_function() == SCREWUP ){ /* congratulations! * You've got a stale file descriptor! */ return; } close(fd); return; }
> >> > You were doing a return if anything went wrong, and you never > >> > cleaned up the MYSQL session, so I suppose you didn't see a need > >> > for the goto before. > >> > >> Yeah, it is not apparent yet from the code, but the MYSQL struct > >> instance, there is a flag called reconnect which I want to check > >> for. I believe if it is 1, then you need to reconnect. I actually > >> want to make that data structure global and to cache the database > >> connection, eventually closing it in the destructor. > > > > Make a big struct (of which the MYSQL connection is one member) and > > pass it around everywhere. Much cleaner than using globals... > > That's a thought but the last time I did that I had to malloc the > structure and I really don't know where to free it since it is being > used in all the lower Widgets.
You have to decide early on. EVERYTHING has a lifecycle. destruct at the end of main() if you have to, or in the handler for Gtk's application_close event or whatever they call it.
> Otherwise it disapears from the tact. > That's why, just for exepedency, I created those dreadful global > structures to store data. You can't just create a structure and then > passing to the callback function at g_pointer a because it disapears > from the darn stack. It took me two days to figure that out this > time, and a week last time (although RMS figured it out in about 15 > seconds in the debugger.)
I think it's a pretty common beginner mistake.
> The wild factor here is that gtk_main() is actually interceeding in > everything here. Roughly speaking, when you click on a button, your > talking to gtk_main() which 'senses' the clicked event and then looks > for the proper callback and then runs it. In this case at least, it > is a darn mine field.
Why is it a mine field?
Loosely coupled objects can make for difficult debugging. It's one of the headaches of abstraction.
> >> I don't know what mysql_init(&MYSQL) does, but it does not allocate > >> any memory. > > > >One thing it does is allocates space for a MYSQL if you pass it a > >NULL. > > Say again? Where did you read that?
http://dev.mysql.com/doc/mysql/en/mysql_init.html
> Then why did I have to make sure the memory was allowed for it?
There are 2 ways to call it.
{ MYSQL db_conn_storage; MYSQL *db_conn = mysql_init(&db_conn_storage); ... mysql_close(db_conn); }
Or if you don't need to manage your own memory:
{ MYSQL *db_conn = mysql_init(0); ... mysql_close(db_conn); }
In the second form, the memory pointed to by db_conn will be free()'ed by mysql_close.
> What the heck does mysql_init() do then. It completely didn't work > otherwise. I'm totally confused now.
I don't know.. Presumably it sets all of the fields of the MYSQL struct to consistent values.
> >> That is the reason for the assignment of the pointer. I hope I'm > >> missing something of the MYSQL API, because otherwise I might end > >> up creating a global flagging system in order to cache the database > >> connection. > > > >Go for it. But not global define a struct. You'll be happy you did.
> I need some rest. I feel like I'm back in College again. I've > crammed for finals relearning 2 dimensional arrays, array function > parameters, the string library, the mysql C API, the GTK C API, patch, > diff, vi advanced features gdb, and C macros all in the last 48 hours, > in addition to trying to remain with a sane program design and boning > up on integration for Biopharmacuetics all in the last 48 hours. > SOMEBODY better be giving me a masters degree when this is done.
Sounds like you're learning a LOT. It's good for you. ____________________________ NYLXS: New Yorker Free Software Users Scene Fair Use - because it's either fair use or useless.... NYLXS is a trademark of NYLXS, Inc
|
|