Regexp help - only guru's have a chance at this one

classic Classic list List threaded Threaded
18 messages Options
Reply | Threaded
Open this post in threaded view
|

Regexp help - only guru's have a chance at this one

Dave Roberts
Hello all,

I have the honor of porting many thousands of lines of DOS code to a
Win32 environment and have the following problem.

At some point in the distant past, the company I'm doing this for must
have thought that using the results of a compare directly would save a
few cycles and that code just kept getting repeated.

In simple form I'm seeing LOTS of this:
z = a == b
x = y - z

The 16-bit compiler they were using returned 1 for TRUE, the 32-bit one
I'm using returns -1 for TRUE so I'm "off by 2" everywhere this is TRUE
(and in many cases means I'm now going passed the end of an array).

I tried using the following regexp with vimgrep:
vimg /[=!<>]\@<!=[^=]\+[=!<>]=/ *.c

which works but has several problems including:
- It matches perfectly legit assignment/compare lines like "if ( (cptr =
malloc(x)) == NULL)"
- It matches many "for" loop lines like "for (i = 0; i <= x; i++ )"
- It does not match if the assignment and conditional are on different lines

Just getting it down to not matching the legit assignment/compare lines
would save me many hours of searching.

Thanks to all who give it a shot...

- Dave
Reply | Threaded
Open this post in threaded view
|

Re: Regexp help - only guru's have a chance at this one

John (Eljay) Love-Jensen
Hi Dave,

I presume you are using Cygwin.

vi $(grep -l '[^=]=[^=].*==' $(find . -type f))

Inside vim...
set hls
/[^=]=[^=].*==

Change...
z = a == b;
...to...
z = (a == b) & 1;

I feel your pain.

HTH,
--Eljay

Reply | Threaded
Open this post in threaded view
|

Re: Regexp help - only guru's have a chance at this one

Dave Roberts
Eljay,

It's a good answer but my problem isn't handling the line when I find it
(although I like the bit manipulation method better than the "(x) ? TRUE
: FALSE" I was doing). The problem is finding the hundreds of actual
problem lines among the tens of thousands of matching lines!

Thanks for trying though,

- Dave

John Love-Jensen wrote:

>Hi Dave,
>
>I presume you are using Cygwin.
>
>vi $(grep -l '[^=]=[^=].*==' $(find . -type f))
>
>Inside vim...
>set hls
>/[^=]=[^=].*==
>
>Change...
>z = a == b;
>...to...
>z = (a == b) & 1;
>
>I feel your pain.
>
>HTH,
>--Eljay
>
>
>  
>
Reply | Threaded
Open this post in threaded view
|

Re: Regexp help - only guru's have a chance at this one

John (Eljay) Love-Jensen
Hi Dave,

The grep and Vim search criteria is what helps find the hundreds of actual
problem lines.

A Vim macro can help put in the parens around the parameter and add the "&
1" (or add the "? TRUE : FALSE" like you had).

Ironically, I rather prefer your solution than my bit twiddling solution.
My solution is less portable and relies on the LSb being set for the
comparison, which isn't necessarily reliable across all possible/potential
platforms.

Good luck!

HTH,
--Eljay

Reply | Threaded
Open this post in threaded view
|

Re: Regexp help - only guru's have a chance at this one

Charles E Campbell Jr
In reply to this post by Dave Roberts
Dave Roberts wrote:

>
> I have the honor of porting many thousands of lines of DOS code to a
> Win32 environment and have the following problem.
>
> At some point in the distant past, the company I'm doing this for must
> have thought that using the results of a compare directly would save a
> few cycles and that code just kept getting repeated.
>
> In simple form I'm seeing LOTS of this:
> z = a == b
> x = y - z
>
> The 16-bit compiler they were using returned 1 for TRUE, the 32-bit
> one I'm using returns -1 for TRUE so I'm "off by 2" everywhere this is
> TRUE (and in many cases means I'm now going passed the end of an array).
>
> I tried using the following regexp with vimgrep:
> vimg /[=!<>]\@<!=[^=]\+[=!<>]=/ *.c
>
> which works but has several problems including:
> - It matches perfectly legit assignment/compare lines like "if ( (cptr
> = malloc(x)) == NULL)"
> - It matches many "for" loop lines like "for (i = 0; i <= x; i++ )"
> - It does not match if the assignment and conditional are on different
> lines
>
> Just getting it down to not matching the legit assignment/compare
> lines would save me many hours of searching.

I was wondering if you can't just place in some common header file that
your s/w is using:

#undef TRUE
#define TRUE 1

Although finding the "z = a == b" style lines may be possible, I'm not
at all sure that such
fixes will address the entire problem, whereas the above two lines have
the virtue of
maintaining the original coders' assumptions (and is a lot simpler to do).

Regards,
Chip Campbell


Reply | Threaded
Open this post in threaded view
|

Re: Regexp help - only guru's have a chance at this one

Dave Roberts
Charles E. Campbell, Jr. wrote:

> Dave Roberts wrote:
>
>>
>> I have the honor of porting many thousands of lines of DOS code to a
>> Win32 environment and have the following problem.
>>
>> At some point in the distant past, the company I'm doing this for
>> must have thought that using the results of a compare directly would
>> save a few cycles and that code just kept getting repeated.
>>
>> In simple form I'm seeing LOTS of this:
>> z = a == b
>> x = y - z
>>
>> The 16-bit compiler they were using returned 1 for TRUE, the 32-bit
>> one I'm using returns -1 for TRUE so I'm "off by 2" everywhere this
>> is TRUE (and in many cases means I'm now going passed the end of an
>> array).
>>
>> I tried using the following regexp with vimgrep:
>> vimg /[=!<>]\@<!=[^=]\+[=!<>]=/ *.c
>>
>> which works but has several problems including:
>> - It matches perfectly legit assignment/compare lines like "if (
>> (cptr = malloc(x)) == NULL)"
>> - It matches many "for" loop lines like "for (i = 0; i <= x; i++ )"
>> - It does not match if the assignment and conditional are on
>> different lines
>>
>> Just getting it down to not matching the legit assignment/compare
>> lines would save me many hours of searching.
>
>
> I was wondering if you can't just place in some common header file
> that your s/w is using:
>
> #undef TRUE
> #define TRUE 1
>
> Although finding the "z = a == b" style lines may be possible, I'm not
> at all sure that such
> fixes will address the entire problem, whereas the above two lines
> have the virtue of
> maintaining the original coders' assumptions (and is a lot simpler to
> do).
>
> Regards,
> Chip Campbell
>
>
>

I'm sorry if I didn't explain the problem very well. TRUE is defined as
1 everywhere in the source (.C's and .H's - at least that stayed
consistent). The problem is that compares are used directly (and not
just in the way I described above - sometimes there are "if (z == TRUE)"
type lines as well).

So, yes, TRUE == 1 but in the above example z == -1 if a == b which does
not match "TRUE", and adds one instead of subtracting when doing x = y - z.

More clear or more muddy?

Thanks,

- Dave

Reply | Threaded
Open this post in threaded view
|

Re: Regexp help - only guru's have a chance at this one

Dave Roberts
In reply to this post by John (Eljay) Love-Jensen
Eljay,

If you look at my original post, I'm using something similar to search
with (except I'm including <=, >=, and != as well as ==) but that
doesn't find the hundreds of lines I want, it finds the hundreds of
lines I want plus the thousands of lines I don't (which is the reason
behind the original post).

Thanks again,

- Dave.

John Love-Jensen wrote:

>Hi Dave,
>
>The grep and Vim search criteria is what helps find the hundreds of actual
>problem lines.
>
>A Vim macro can help put in the parens around the parameter and add the "&
>1" (or add the "? TRUE : FALSE" like you had).
>
>Ironically, I rather prefer your solution than my bit twiddling solution.
>My solution is less portable and relies on the LSb being set for the
>comparison, which isn't necessarily reliable across all possible/potential
>platforms.
>
>Good luck!
>
>HTH,
>--Eljay
>
>
>  
>
Reply | Threaded
Open this post in threaded view
|

Re: Regexp help - only guru's have a chance at this one

Matthew Winn
In reply to this post by Dave Roberts
On Mon, Sep 19, 2005 at 10:24:54AM -0400, Dave Roberts wrote:
> Eljay,
>
> It's a good answer but my problem isn't handling the line when I find it
> (although I like the bit manipulation method better than the "(x) ? TRUE
> : FALSE" I was doing). The problem is finding the hundreds of actual
> problem lines among the tens of thousands of matching lines!

"(x) ? 1 : 0" would be better than using TRUE and FALSE, as that's what
the original coders intended.  (I once used a buggy compiler where true
comparisons returned 1 in the lower 16 bits and whatever value happened
to be in a certain register in the upper 16 bits.  That one forced you
to ignore the real value of truth, though not by design.)

I don't think a solution to your problem exists in the general case, as
comparisons may be arbitrarily complex.  If there's some restriction on
the complexity of the comparison then it will be possible to construct
a regex to match them.  If any expression could be involved then it's
impossible, and the best you can hope for is a regex that matches all
the lines you want but gives false positives, and then step through all
the matches one by one.  If the number of false matches is low that
might be enough.

Do you have any real code you can show?

--
Matthew Winn ([hidden email])
Reply | Threaded
Open this post in threaded view
|

Re: Regexp help - only guru's have a chance at this one

Tim Chase-2
In reply to this post by Dave Roberts
Dave,

I don't know how many files you have, or how many subdirs you've
got, but perhaps something like the following would do the trick?

        vim *.c somedir\*.c otherdir\*.c
        :set hidden
        :argdo
%s/^\s*\<\(\w\+\)\>\s*=\s*\(.*==.*\)\_$\(\_s*\w\+\)\s*=\s*.*-\s*\1/\1
= (\2) \& 1\3/e

The first trick is to get all the possible files in as arguments
(or buffers or whatever).  Any and all files should do, as it
should skip any places such an event isn't found.  I did note
that you didn't have any semi-colons in there, so if these truely
are C files, you'll need to insert something like

        \s*;\s*

before the "\_$" in the search expression.  You might also want
to change the "\1/\1" portion to "\1\s*;/\1"

I'm sure there are some spurious edge cases on this, but it seems
to find all the test-cases I threw at it.  I'm using Eljay's "(x
== y) & 1" hack which was short, sweet, and doesn't require an
evaluation/branch instruction which mungs with branch-prediction
hardware :)

If you know that it's always of your described form, and not
sub-expressions such as

        z = foo & bar + 32 == baz - bork
        c = stuff + thing - z

then you can tighten up those expressions a bit, changing the
".*" portions to "\w\+".

You can then survey your files to ensure that nothing greviously
broke, and then use

        :wall

to write all the changed files.

If you find other edge cases that this misses and should catch,
or catches and should miss, then further details about those
scenarios might help diagnose the matter.

Hope this helps,

-tim





Reply | Threaded
Open this post in threaded view
|

Re: Regexp help - only guru's have a chance at this one

Dave Roberts
In reply to this post by Matthew Winn
Matthew Winn wrote:

>On Mon, Sep 19, 2005 at 10:24:54AM -0400, Dave Roberts wrote:
>  
>
>>Eljay,
>>
>>It's a good answer but my problem isn't handling the line when I find it
>>(although I like the bit manipulation method better than the "(x) ? TRUE
>>: FALSE" I was doing). The problem is finding the hundreds of actual
>>problem lines among the tens of thousands of matching lines!
>>    
>>
>
>"(x) ? 1 : 0" would be better than using TRUE and FALSE, as that's what
>the original coders intended.  (I once used a buggy compiler where true
>comparisons returned 1 in the lower 16 bits and whatever value happened
>to be in a certain register in the upper 16 bits.  That one forced you
>to ignore the real value of truth, though not by design.)
>
>I don't think a solution to your problem exists in the general case, as
>comparisons may be arbitrarily complex.  If there's some restriction on
>the complexity of the comparison then it will be possible to construct
>a regex to match them.  If any expression could be involved then it's
>impossible, and the best you can hope for is a regex that matches all
>the lines you want but gives false positives, and then step through all
>the matches one by one.  If the number of false matches is low that
>might be enough.
>  
>

The number of false positives with "[=!<>]\@<!=[^=]\+[=!<>]=" is very,
very high - most of them of the form:
((a = func(x)) == 0)

>Do you have any real code you can show?
>
>  
>

An example line is:
          pstAppInfo->stInput.stFix.stDtl.bMarkDown = (long)
toupper(szInput[0]) == 'Y';

and then in the calling function there's a:
          if( pstAppInfo->stInput.stFix.stDtl.bMarkDown == TRUE )

The regexp I'm using finds it just fine - it also finds the:
    nReturn = fnGetKey(szInput, szInput, 2, (nScrWidth == 20 ? 18 : 19),
"", 1, 1, dwFlag);

as well as the malloc's before it. I think you're right - I'm in for a
long day of searching.

Thanks anyway,

- Dave

Reply | Threaded
Open this post in threaded view
|

Re: Regexp help - only guru's have a chance at this one

Dave Roberts
In reply to this post by Tim Chase-2
Tim Chase wrote:

> Dave,
>
> I don't know how many files you have, or how many subdirs you've got,
> but perhaps something like the following would do the trick?
>
>     vim *.c somedir\*.c otherdir\*.c
>     :set hidden
>     :argdo
> %s/^\s*\<\(\w\+\)\>\s*=\s*\(.*==.*\)\_$\(\_s*\w\+\)\s*=\s*.*-\s*\1/\1
> = (\2) \& 1\3/e
>
> The first trick is to get all the possible files in as arguments (or
> buffers or whatever).  Any and all files should do, as it should skip
> any places such an event isn't found.  I did note that you didn't have
> any semi-colons in there, so if these truely are C files, you'll need
> to insert something like
>
>     \s*;\s*
>
> before the "\_$" in the search expression.  You might also want to
> change the "\1/\1" portion to "\1\s*;/\1"
>
> I'm sure there are some spurious edge cases on this, but it seems to
> find all the test-cases I threw at it.  I'm using Eljay's "(x == y) &
> 1" hack which was short, sweet, and doesn't require an
> evaluation/branch instruction which mungs with branch-prediction
> hardware :)
>
> If you know that it's always of your described form, and not
> sub-expressions such as
>
>     z = foo & bar + 32 == baz - bork
>     c = stuff + thing - z
>
> then you can tighten up those expressions a bit, changing the ".*"
> portions to "\w\+".
>
> You can then survey your files to ensure that nothing greviously
> broke, and then use
>
>     :wall
>
> to write all the changed files.
>
> If you find other edge cases that this misses and should catch, or
> catches and should miss, then further details about those scenarios
> might help diagnose the matter.
>
> Hope this helps,
>
> -tim
>

Hmm. Just to see what the regexp would match I cut and paste and ran this:
vimg /^\s*\<\(\w\+\)\>\s*=\s*\(.*==.*\)\_$\(\_s*\w\+\)\s*=\s*.*-\s*\1/ *.c

and got no matches.

I think the reason is this regexp is specific to the simplified example.
The actual code generally had #ifdef'd debug lines between the
assignment and the use (plus the use may just be comparing it to TRUE).

The regexp I was looking for would stay with one statement (even if the
statement was on multiple lines) and ignore ((a = b) == c) type lines
and "for" loop lines.

Thanks anyway,

- Dave
Reply | Threaded
Open this post in threaded view
|

Re: Regexp help - only guru's have a chance at this one

Charles E Campbell Jr
In reply to this post by Dave Roberts
Dave Roberts wrote:

> Charles E. Campbell, Jr. wrote:
>
>>
>> I was wondering if you can't just place in some common header file
>> that your s/w is using:
>>
>> #undef TRUE
>> #define TRUE 1
>>
>> Although finding the "z = a == b" style lines may be possible, I'm
>> not at all sure that such
>> fixes will address the entire problem, whereas the above two lines
>> have the virtue of
>> maintaining the original coders' assumptions (and is a lot simpler to
>> do).
>>
>> Regards,
>> Chip Campbell
>>
>>
>>
>
> I'm sorry if I didn't explain the problem very well. TRUE is defined
> as 1 everywhere in the source (.C's and .H's - at least that stayed
> consistent). The problem is that compares are used directly (and not
> just in the way I described above - sometimes there are "if (z ==
> TRUE)" type lines as well).
>
> So, yes, TRUE == 1 but in the above example z == -1 if a == b which
> does not match "TRUE", and adds one instead of subtracting when doing
> x = y - z.
>
> More clear or more muddy?


Sorry -- I realized that my suggestion wouldn't work (just after hitting
the send), but obviously the cancel
button doesn't cancel.  Sigh.

Here's another suggestion:  apply
========================================================
%s/\(\%([-+]\=\d\%(\.\d\+\)\=\%([eE][-+]\=\d\+\)\=\)\|\h\w*\)\s*==\s*\(\%([-+]\=\d\%(\.\d\+\)\=\%([eE][-+]\=\d\+\)\=\)\|\h\w*\)/((\1==\2)?1:0)/ge
========================================================
(everything between the long ===s are to be on one line)  (also, place
into a file, such as "eefix.vim")

This substitute will undoubtedly "fix" some things that you don't want
fixed.
You could use the left-hand-side of it to pick off files if you wish.

I suggest applying the fix (but keep a copy of your original source).  
Compile.
If but a few errors show up, fix 'em, otherwise  if there's a bunch that
are similar,
come up with a second substitute to handle those cases. and put the
substitute
into eefix.vim.  Repeat as needed.

Regards,
Chip Campbell


Reply | Threaded
Open this post in threaded view
|

Re: Regexp help - only guru's have a chance at this one

Bram Moolenaar
In reply to this post by Dave Roberts

Dave Roberts wrote:

> >> I have the honor of porting many thousands of lines of DOS code to a
> >> Win32 environment and have the following problem.
> >>
> >> At some point in the distant past, the company I'm doing this for
> >> must have thought that using the results of a compare directly would
> >> save a few cycles and that code just kept getting repeated.
> >>
> >> In simple form I'm seeing LOTS of this:
> >> z = a == b
> >> x = y - z
> >>
> >> The 16-bit compiler they were using returned 1 for TRUE, the 32-bit
> >> one I'm using returns -1 for TRUE so I'm "off by 2" everywhere this
> >> is TRUE (and in many cases means I'm now going passed the end of an
> >> array).

That is weird.  All C compilers I know use 1 for the result of a boolean
expression.  It might not be in the standard, but that is what most
programmers expect (and quite often rely on).

Doesn't the compiler have a configuration option to change this?

--
Not too long ago, compress was something you did to garbage...

 /// Bram Moolenaar -- [hidden email] -- http://www.Moolenaar.net   \\\
///        Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\              Project leader for A-A-P -- http://www.A-A-P.org        ///
 \\\     Buy LOTR 3 and help AIDS victims -- http://ICCF.nl/lotr.html   ///
Reply | Threaded
Open this post in threaded view
|

Re: Regexp help - only guru's have a chance at this one

Dave Roberts
Bram Moolenaar wrote:

>Dave Roberts wrote:
>
>  
>
>>>>I have the honor of porting many thousands of lines of DOS code to a
>>>>Win32 environment and have the following problem.
>>>>
>>>>At some point in the distant past, the company I'm doing this for
>>>>must have thought that using the results of a compare directly would
>>>>save a few cycles and that code just kept getting repeated.
>>>>
>>>>In simple form I'm seeing LOTS of this:
>>>>z = a == b
>>>>x = y - z
>>>>
>>>>The 16-bit compiler they were using returned 1 for TRUE, the 32-bit
>>>>one I'm using returns -1 for TRUE so I'm "off by 2" everywhere this
>>>>is TRUE (and in many cases means I'm now going passed the end of an
>>>>array).
>>>>        
>>>>
>
>That is weird.  All C compilers I know use 1 for the result of a boolean
>expression.  It might not be in the standard, but that is what most
>programmers expect (and quite often rely on).
>
>Doesn't the compiler have a configuration option to change this?
>
>  
>

Probably - This is Visual Studio 2003 .NET - They have options for
everything if you know where to look (I'm still crawling though - It's
like VIM in that I've learned and regularly use dozens of commands but
realize that I don't know 10% of the capabilities)

Actually, it seems like -1 would be a better value for TRUE... FALSE is
all bits off, TRUE is all bits on so you could compare against any of
them. Just my opinion but, then again, I've never tried using the
results of a compare directly. Another responder told of a compiler that
returned unpredictable (but non-0) results.

- Dave
Reply | Threaded
Open this post in threaded view
|

Re: Regexp help - only guru's have a chance at this one

Dave Roberts
In reply to this post by Charles E Campbell Jr
Charles E. Campbell, Jr. wrote:

> Dave Roberts wrote:
>
>> Charles E. Campbell, Jr. wrote:
>>
>>>
>>> I was wondering if you can't just place in some common header file
>>> that your s/w is using:
>>>
>>> #undef TRUE
>>> #define TRUE 1
>>>
>>> Although finding the "z = a == b" style lines may be possible, I'm
>>> not at all sure that such
>>> fixes will address the entire problem, whereas the above two lines
>>> have the virtue of
>>> maintaining the original coders' assumptions (and is a lot simpler
>>> to do).
>>>
>>> Regards,
>>> Chip Campbell
>>>
>>>
>>>
>>
>> I'm sorry if I didn't explain the problem very well. TRUE is defined
>> as 1 everywhere in the source (.C's and .H's - at least that stayed
>> consistent). The problem is that compares are used directly (and not
>> just in the way I described above - sometimes there are "if (z ==
>> TRUE)" type lines as well).
>>
>> So, yes, TRUE == 1 but in the above example z == -1 if a == b which
>> does not match "TRUE", and adds one instead of subtracting when doing
>> x = y - z.
>>
>> More clear or more muddy?
>
>
>
> Sorry -- I realized that my suggestion wouldn't work (just after
> hitting the send), but obviously the cancel
> button doesn't cancel.  Sigh.
>
> Here's another suggestion:  apply
> ========================================================
> %s/\(\%([-+]\=\d\%(\.\d\+\)\=\%([eE][-+]\=\d\+\)\=\)\|\h\w*\)\s*==\s*\(\%([-+]\=\d\%(\.\d\+\)\=\%([eE][-+]\=\d\+\)\=\)\|\h\w*\)/((\1==\2)?1:0)/ge
>
> ========================================================
> (everything between the long ===s are to be on one line)  (also, place
> into a file, such as "eefix.vim")
>
> This substitute will undoubtedly "fix" some things that you don't want
> fixed.
> You could use the left-hand-side of it to pick off files if you wish.
>
> I suggest applying the fix (but keep a copy of your original source).  
> Compile.
> If but a few errors show up, fix 'em, otherwise  if there's a bunch
> that are similar,
> come up with a second substitute to handle those cases. and put the
> substitute
> into eefix.vim.  Repeat as needed.
>
> Regards,
> Chip Campbell
>
>

Beauty of regexp Dr. C but it's matching all the "if (a == b)" lines - I
think I'm straining the quickfix window with this one... :)

- Dave
Reply | Threaded
Open this post in threaded view
|

Re: Regexp help - only guru's have a chance at this one (update)

Dave Roberts
In reply to this post by Dave Roberts
Dave Roberts wrote:

> Hello all,
>
> I have the honor of porting many thousands of lines of DOS code to a
> Win32 environment and have the following problem.
>
> At some point in the distant past, the company I'm doing this for must
> have thought that using the results of a compare directly would save a
> few cycles and that code just kept getting repeated.
>
> In simple form I'm seeing LOTS of this:
> z = a == b
> x = y - z
>
> The 16-bit compiler they were using returned 1 for TRUE, the 32-bit
> one I'm using returns -1 for TRUE so I'm "off by 2" everywhere this is
> TRUE (and in many cases means I'm now going passed the end of an array).
>
> I tried using the following regexp with vimgrep:
> vimg /[=!<>]\@<!=[^=]\+[=!<>]=/ *.c
>
> which works but has several problems including:
> - It matches perfectly legit assignment/compare lines like "if ( (cptr
> = malloc(x)) == NULL)"
> - It matches many "for" loop lines like "for (i = 0; i <= x; i++ )"
> - It does not match if the assignment and conditional are on different
> lines
>
> Just getting it down to not matching the legit assignment/compare
> lines would save me many hours of searching.
>
> Thanks to all who give it a shot...
>
> - Dave
>

I noticed that most of my false positives were of the form "if ((a = b)
!= c)" meaning there was a right paren and optional space before the ==,
!=, <=, or >=.

I added a check for that to my original vimgrep line:
vimg /[=!<>]\@<!=[^=]\+\() *\)\@<![=!<>]=/ *.cpp

and reduced matches by about 70%. Most of my false positives now are in
for-loop lines.

This still wont find matches across lines but this is way better for now.

Thanks to everyone...

- Dave

Reply | Threaded
Open this post in threaded view
|

Re: Regexp help - only guru's have a chance at this one

Gary Johnson
In reply to this post by Bram Moolenaar
On 2005-09-19, Bram Moolenaar <[hidden email]> wrote:

> Dave Roberts wrote:
>
> > >> I have the honor of porting many thousands of lines of DOS code to a
> > >> Win32 environment and have the following problem.
> > >>
> > >> At some point in the distant past, the company I'm doing this for
> > >> must have thought that using the results of a compare directly would
> > >> save a few cycles and that code just kept getting repeated.
> > >>
> > >> In simple form I'm seeing LOTS of this:
> > >> z = a == b
> > >> x = y - z
> > >>
> > >> The 16-bit compiler they were using returned 1 for TRUE, the 32-bit
> > >> one I'm using returns -1 for TRUE so I'm "off by 2" everywhere this
> > >> is TRUE (and in many cases means I'm now going passed the end of an
> > >> array).
>
> That is weird.  All C compilers I know use 1 for the result of a boolean
> expression.  It might not be in the standard, but that is what most
> programmers expect (and quite often rely on).

Yes, that compiler is broken.  I would suggest fixing or replacing
the compiler as the best solution.  Who knows what else it might
(subtly) screw up.  Also, you can't dependably use it to compile any
C source, not just the code you're currently working on, without
searching for all such uses of logical expressions.

From K&R2, p. 44:

    Relational expressions like i > j and logical expressions
    connected by && and || are defined to have value 1 if true,  and
    0 if false.

Gary

--
Gary Johnson                 | Agilent Technologies
[hidden email]     | Wireless Division
                             | Spokane, Washington, USA
Reply | Threaded
Open this post in threaded view
|

Re: Regexp help - only guru's have a chance at this one

adah
In reply to this post by Dave Roberts
Dave Roberts wrote:

>> That is weird.  All C compilers I know use 1 for the result of a
>> boolean expression.  It might not be in the standard, but that is
>> what most programmers expect (and quite often rely on).
>>
>> Doesn't the compiler have a configuration option to change this?
>
> Probably - This is Visual Studio 2003 .NET - They have options for
> everything if you know where to look (I'm still crawling though - It's
> like VIM in that I've learned and regularly use dozens of commands but
> realize that I don't know 10% of the capabilities)
>
> Actually, it seems like -1 would be a better value for TRUE... FALSE
> is all bits off, TRUE is all bits on so you could compare against any
> of them. Just my opinion but, then again, I've never tried using the
> results of a compare directly. Another responder told of a compiler
> that returned unpredictable (but non-0) results.
>
> - Dave

Are you sure, Dave?  I have tested on Microsoft Visuall C++ Toolkit 2003
(CL 13.10.3052), and with the default settings a boolean expression
returns 0 or 1, whether in C or C++.  I suppose Visual Studio 2003 .NET
uses the same compiler.

Best regards,

Yongwei