On Thursday 28 October 2010 05:55, Rob Landley wrote:
> > > You see a significant difference between scalar and pointer types?
> >
> > This is not the point. The point is:
> >
> > ...
> > ...
> > ...
> > const re_dfa_t *const dfa = mctx->dfa;
> > reg_errcode_t err;
> > int match = 0;
> > int match_last = -1;
> > int cur_str_idx = re_string_cur_idx (&mctx->input);
> > re_dfastate_t *cur_state;
> > int at_init_state = p_match_first != NULL;
> > int next_start_idx = cur_str_idx;
> >
> > err = REG_NOERROR;
> > cur_state = acquire_init_state_context (&err, mctx, cur_str_idx);
> > /* An initial state must not be NULL (invalid). */
> > if (BE (cur_state == NULL, 0))
> > {
> > assert (err == REG_ESPACE);
> > return -2;
> > }
> >
> > if (mctx->state_log != NULL)
> > {
> > mctx->state_log[cur_str_idx] = cur_state;
> >
> > /* Check OP_OPEN_SUBEXP in the initial state in case that we use them
> > later. E.g. Processing back references. */
> > if (BE (dfa->nbackref, 0))
> > {
> > at_init_state = 0;
> > err = check_subexp_matching_top (mctx, &cur_state->nodes, 0);
> > if (BE (err != REG_NOERROR, 0))
> > return err;
> >
> > if (cur_state->has_backref)
> > {
> > err = transit_state_bkref (mctx, &cur_state->nodes);
> > if (BE (err != REG_NOERROR, 0))
> > return err;
> > }
> > }
> > }
> >
> > /* If the RE accepts NULL string. */
> > if (BE (cur_state->halt, 0))
> > {
> > if (!cur_state->has_constraint
> >
> > || check_halt_state_context (mctx, cur_state, cur_str_idx))
> >
> > {
> > if (!fl_longest_match)
> > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > return cur_str_idx;
> > else
> > {
> > match_last = cur_str_idx;
> > match = 1;
> > }
> > }
> > }
> >
> > Rob, can you figure out whether fl_longest_match is a number? or bool?
> > or maybe a string (that is, char*) in the underlined if() statement?
>
> A) I do python development, which means I've learned when I don't have to
> _care_. :)
>
> B) I stopped reading at about REG_NOERROR, with the mental note "there is no
> way turning a !x into an X == 0 will make any significant difference to the
> readability of this code.
>
> C) ==0 doesn't tell you if it's a char, short, int, long, signed, unsigned,
> and doesn't rule _out_ it being a pointer.
Strictly speaking, yes, it doesn't. If the code is written by
people enchanted with the strange logic of C/C++ that
"0 constant can be a null pointer of any type", then yes,
x == 0 can actully mean "x is a null pointer".
Luckily, I know (as opposed to "I think") that this is stupid,
because Linus also says so.
Back to my interpretation of x == 0 versus x == NULL versus !x.
Assuming I read above mess for a first time, hunting down a bug,
and don't understand the logic yet,
when I see "!fl_longest_match" I think "it's likely a pointer
or a bool, and judging by its name it's a bool",
whereas when I see "fl_longest_match != 0" I think "looks like it's
and integer - perhaps a length of the longest match seen so far".
This helps me to understand the logic faster
than if I'd need to go and find its definition.
The width and signedness of integer is less important
for figuring out the logic that the fact that it is an *integer*.
The snippet above has an example where it _has_ such
more readable comparison: "if (mctx->state_log != NULL)" -
immediately tells you that state_log is a pointer.
(By name alone it could be a bool too)
However, here it isn't useful, since the very next line
uses mctx->state_log[x] and thus reveals "pointer-ness" anyway.
> That's actually how I first got involved with Tinycc:
>
> http://bellard.org/otcc/
>
> The contest had a size limit of 2048 bytes for entries, and Fabrice Bellard
> submitted a compiler for a subset of C, capable of rebuilding itself from
> source code.
>
> He won "best abuse of the rules", and then untangled his entry and expanded
> it
> into a full c99 compiler.
>
> Its main advantage was speed: it was so fast he added a "-run" mode that let
> you set the executable bit on a C file, start it with "#!/usr/bin/tcc -run"
> (plus -lpthreads or whatever else you needed), and use C as a scripting
> language. Yes, with X11 and everything, if you liked.
>
> The main disadvantage was that it produced x86 machine code directly so was
> hard to retarget for different processors (or even x86-64), and while
> refactoring it to have a front end and back end he could decouple from each
> other (and thus have multiple code generator back ends for various
> sarchitectures), he started to wonder about what kind of _front_ ends he
> could
> swap out with. Specifically, he wanted something that would parse x86
> machine
> code a page at a time, translate it to native code on the fly, and run x86
> binaries (specifically wine) on non-x86 platforms.
>
> The new project this led to was called "qemu", and it sucked away so much of
> his time tinycc stalled. It's been revived by windows guys, but all they do
> is windows development and they don't really care about linux or non-x86
> targets.
Pity, eh? Where is the cloning machine when you need it...
> I prefer "!x" to "x==0" because it takes up less horizontal space (less eye
> movement, less likelihood of wrapping off the edge of the screen), because
> the
> ! always has to go at the beginning and you can have x == 0 and 0 == x as
> synonyms, because "x=0" means something different but looks the same and is
> easy to miss (hence some gurus recommend "4 == x" programming style with the
> constant on the left so you CAN'T typo up an assignment, but algebra leads
> math people to phrase it the other way, so you see both in the wild), because
> "x == 0" and "x == NULL" and "x == EXIT_SUCCESS" and "x == STDIN_FILENO" and
> so on mean exactly the same thing but look gratuitously different...
I see your point.
--
vda
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox