| Store | Cart

Python style guidelines

From: MetalOne <j...@iteris.com>
13 Mar 2004 13:28:26 -0800
> It's that "resources acquired" part that messes people up.  I've> seen it over and over and over again.  Memory leaks.  Dangling> pointers.  Unrecoverable file handles.  Especially as functions> that acquire lots of resources evolve over time and someone adds> code to acquire another resource or detect another error condition> and then doesn't find all the subsequent exit points.  It's less> of an issue with languages with proper garbage collection, but it> can be a real nightmare in (e.g.) C or assembler.  Unit tests that> cover all possible resource leaks are difficult to construct> correctly.  C++ partially addresses the problem with RIAA (if> coders use it properly) and a hodgepodge of "smart" objects that> do pseudo self-garbage collection.> > A single exit point also gives me a fighting chance to add> something to the logical end of a function, like setting the "I'm> done" flag or logging the result.> > If I know that my function only has one exit point, then it's also> easier to add "let's see what this function is returning"> debugging code, because I know exactly where to put it and where> to look for it later when I want to take it out.  In some systems,> the fact that a given function reaches its (single) exit point is> extremely valuable information.> > OTOH, I'm usually the first one to stand up at a design review and> declare that some function or some method is too long or too> complex and should be broken up *before* such problems occur.> > And that all said, I agree that a bunch of pre-checks and a quick> exit, BEFORE DOING ANYTHING ELSE, near the top of a function can> make the rest of some functions much more clear.  Again, I've seen> it a million times:  I'll add one more validation down here, but> forget to release that memory we just acquired up there.> 
Good points.
With resource acquistion, I was mainly thinking along the lines of

int file_compare(const char *filename1, const char *filename2)
{
    FILE *infile1 = fopen(filename1, "r");
    FILE *infile2 = fopen(filename2, "r");
    if (!infile1 || !infile2)
    {
        // error
        if (infile2)
            fclose(infile2);
        if (infile1)
            fclose(infile1);
        return FAILURE;
    }
    
    // compare files
    return SUCCESS
}

as opposed to

int file_compare(const char *filename1, const char *filename2)
{
    int result = SUCCESS;
    FILE *infile1 = fopen(filename1, "r");
    if (infile1)
    {
        FILE *infile2 = fopen(filename2, "r");
        if (infile2)
        {   
            // compare files
        }
        else
        {
            result = FAILURE;
        }
    }
    else
    {
        result = FAILURE;
    }
    if (infile2)
        fclose(infile2);
    if (infile1)
        fclose(infile1);
    return result;
}

Recent Messages in this Thread
beli...@aol.com Mar 10, 2004 07:12 pm
Skip Montanaro Mar 10, 2004 10:09 pm
Will Berry Mar 11, 2004 10:39 pm
Richie Hindle Mar 12, 2004 09:36 am
Jorgen Grahn Mar 12, 2004 07:29 pm
MetalOne Mar 13, 2004 07:08 am
Heather Coppersmith Mar 13, 2004 01:22 pm
MetalOne Mar 13, 2004 09:28 pm
Andy Salnikov Mar 15, 2004 09:34 pm
Rocco Moretti Mar 17, 2004 07:22 pm
wmwd...@sneakemail.com ) (Greg Ewing (using news.cis.dfn.de) Mar 15, 2004 12:39 am
Josef Meile Mar 11, 2004 09:48 am
Peter Otten Mar 11, 2004 11:18 am
Heather Coppersmith Mar 11, 2004 11:34 am
Josef Meile Mar 11, 2004 03:39 pm
Peter Hansen Mar 11, 2004 03:41 pm
Donn Cave Mar 11, 2004 04:49 pm
John Roth Mar 11, 2004 05:16 pm
wmwd...@sneakemail.com ) (Greg Ewing (using news.cis.dfn.de) Mar 12, 2004 03:23 am
Mel Wilson Mar 12, 2004 03:57 pm
Aahz Mar 11, 2004 04:27 pm
beli...@aol.com Mar 11, 2004 12:52 pm
Michael Hudson Mar 11, 2004 01:41 pm
Messages in this thread