[PATCH] osutil: implementation for Win32
Adrian Buehlmann
adrian at cadifra.com
Wed Sep 10 14:05:26 CDT 2008
On 10.09.2008 20:51, Matt Mackall wrote:
> On Wed, 2008-09-10 at 15:53 +0200, Adrian Buehlmann wrote:
>> On 09.09.2008 21:51, Matt Mackall wrote:
>>> On Tue, 2008-09-09 at 20:51 +0200, Adrian Buehlmann wrote:
>>>> # HG changeset patch
>>>> # User Petr Kodl <petrkodl at gmail.com>
>>>> # Date 1220959680 14400
>>>> # Node ID 020fe75b47f569a29c25f8a5fef7451100d72772
>>>> # Parent 9141bebefe3ed0498ff07271214bfca8b4eb0d27
>>>> osutil: implementation for Win32
>>> Thanks, guys. This is looking much better. A few more comments, I'm
>>> afraid.
>>>
>>>> +static PyObject *listdir(PyObject *self, PyObject *args, PyObject *kwargs)
>>>> +{
>>>> + PyObject *statobj = NULL;
>>>> + PyObject *list = NULL;
>>>> + PyObject *items = NULL;
>>>> + PyObject *ctor_args = NULL;
>>>> + PyObject *item0 = NULL;
>>>> + PyObject *item1 = NULL;
>>>> + PyObject *py_st = NULL;
>>> There's a slightly weird thing going on here with initializing
>>> variables.
>> Does that mean those variables should not be initialized?
>
> Yes.
>
>> Why is initializing these variables weird?
>
> a) it's unnecessary
> b) it makes the source uglier
> c) it makes the compiled code bigger
> d) it can hide real uninitialized variable bugs that a compiler may spot
>
>> Or are you referring to some specific of these variables?
>>
>> It seems to me the preexisting (unix) listdir implementation does something
>> very similar with variable initializations:
>
> And that's wrong too. Perhaps I'll fix it. Some time in October at this
> rate.
I see.
> (This is a small example of why code review is important. If we let in
> suboptimal code, it serves as a template for further suboptimal code.
> The UNIX version actually looked worse than the original proposed
> Windows code when it initially went in and I spent several hours beating
> it into shape before running out of steam.)
That's indeed a problem for the learners like myself.
I constantly think the code that is already there must be ok.
>>> I eventually figured out it's because of a misunderstanding
>>> of how the 'goto' error-handling style works. It's supposed to work
>>> roughly like this:
>>>
>>> a = malloc(x);
>>> ret = NO_MEMORY;
>>> if (!a)
>>> goto error_a;
>>>
>>> b = open(y);
>>> ret = OPEN_FAILED;
>>> if (!b)
>>> goto error_b;
>>>
>>> ret = OOPS;
>>> do {
>>> if (!trysomething(a,b))
>>> goto error;
>>> ...
>>> }
>>> ret = SUCCESS;
>>>
>>> error: /* need to free all resources */
>>> close(b);
>>> error_b: /* don't need to close b, because we didn't open it */
>>> free(a);
>>> error_a: /* don't need to free a */
>>> return ret;
>>>
>>> The idea is that you can bail out easily anywhere in your function even
>>> if there are already some resources allocated that need cleaning up and
>>> not have the error handling paths dominate your code or cause massive
>>> indenting.
>> You have omitted the declaration of variables.
>
> Yes, I'm lazy. Variables should be declared and the meaningless
> initializers skipped.
Ok. Got that. I didn't understand that there are meaningless initializers.
>>> To make this work, you don't have to do anything special with variable
>>> initialization
>> What has been done special about variable initialization in the patch?
>
> Not only is every variable initialized to an "unused" state, every
> variable has to be set -back- to the "unused" state after use so the
> exit code does the right thing. This is both more complicated and more
> fragile than the preferred style where we 'statically' know which
> variables are in what state based simply on what line of code we're on
> without the extra initialization and re-initialization. Eg: on all the
> lines above between 'goto error_b' and 'error_b:', we know that a and b
> are properly initialized.
Thank you for your explanation and your patience.
More information about the Mercurial-devel
mailing list