-
Re: Why integer and int32
Dan Barclay <Dan@MVPs.org> wrote:
>> Writing the code differently (as [Loop While FlagSet <> &HFFFF])
would have made it
>> explicit, very understandable, and unaffected by the Int16 to Int32
>> change.
>
> Would it have? Try that in VB6, with FlagSet As Long to change the
> data size. I'd have to pull it up and try it, but my bet is that
> you'll find that &HFFFF is -1 and that the code would fail.
>
> The &HFFFF isn't just a bit pattern, it's a number. What number it
> turns out to be is determined by the *default* data size. Dunno what
> that default size is for VB.net (today) nor do I know that the default
> size will be in future versions. Lesson: when you start changing data
> sizes you have to look at *all* the details to find out what's going
> to happen. Since they're free to change them then you do *not* know
> what &HFFFF means.
FWIW, I did try it using the &HFFFF construct, and it does work whether
FlagSet is a (VB6 & earlier) Integer or Long, or a VB.NET Integer or
Long. My main problem was coming up with a simple CheckStatus function
that could easily handle setting bit 15. I understand that it's a
number - as well as a bit pattern. My point as been that as long as you
keep all the code working with in bit pattern terms (e.g., using [Loop
While FlagSet <> &HFFFF]), you should be okay. It's when you start
mixing bit patterns with numbers (e.g., [Loop While Not FlagSet]) that
you can get tripped up.
> (#6)
> Error 51
> Error 3
> Error 9
> ...
Now, I've finally got to ask - what is the significance of that part of
the tagline? Of one thing I'm sure - that it has something to do with
your feelings about VB.NET.
--
Greg
-
Re: Why integer and int32
Dan Barclay <Dan@MVPs.org> wrote:
> You'd better go try it again, or show me your code. My bet is that
> you didn't really set (only) the lower 16bits. If the lower 16bits of
> a 32 bit FlagSet are set, your test against &HFFFF will show false in
> VB5. Here's the code:
>
> Dim FlagSet As Long
> FlagSet = &HFFFF& ' set lower 16 bits only (note force to long)
> Debug.Print FlagSet
> If FlagSet = &HFFFF Then
> Debug.Print "it worked"
> Else
> Debug.Print "it failed"
> End If
Here's my stuff (run in VB6 SP5):
===================================
Option Explicit
'--------------------------------------------------
Function CheckStatus(nBit As Integer) As Integer
' - dummy code to always return with bit set on
If (nBit < 0) Or (nBit > 15) Then
CheckStatus = 0
ElseIf (nBit = 15) Then
CheckStatus = &H8000
Else
CheckStatus = (2 ^ nBit)
End If
End Function
'--------------------------------------------------
Private Sub Form_Load()
Dim BitNum As Integer
Dim FlagSet As Long ' Integer
Do
For BitNum = 0 To 15
FlagSet = FlagSet Or CheckStatus(BitNum)
Next
Loop Until FlagSet = &HFFFF
MsgBox "We're Done", vbInformation
End
End Sub
===================================
I ran it with FlagSet defined as both a Long and an Integer, and it
worked both times. I also ran your code, and got an "it failed". I
can't come up with a good reason for this apparent discrepancy, but my
brains a bit tired right now. (Maybe VB's just being accomodating to
both of our POV's <g>).
>> My main problem was coming up with a simple CheckStatus function
>> that could easily handle setting bit 15.
>
> Not a problem (or the issue), and in fact it may be data that
> originates in hardware or from an API call.
I realize that it would likely come from someplace else - I was just
trying to come up with a simple simulation routine, and will get an
overflow error if I don't trap for nBit=15. I'm sure that my solution
(above), can be improved upon.
>> I understand that it's a
>> number - as well as a bit pattern. My point as been that as long as
>> you keep all the code working with in bit pattern terms (e.g., using
>> [Loop While FlagSet <> &HFFFF]), you should be okay.
>
> You would be fine so long as you programmed to known data sizes and
> the data sizes don't change. If the data sizes change then all bets
> are off and you'd better review your code *in detail*. See above.
>
> Secondly, you only have numbers to use as containers for bit patterns.
> This isn't exactly to the point, but see
> http://www.mvps.org/vb/tips/truth.htm . Bottom line: It's *all* in
> the numbers.
I've read your white paper (twice). I don't think that it applies here.
I realize that we are using numbers to hold the bit patterns. My point
continues to be (and I think is validated by the above code), that since
you were trying to check if all 16 bits were turned on, the comparison
to &HFFFF would do that regardless if it was in a 16 or 32 bit number.
I think that it's also much more clear for someone who is trying to pick
up the code. The whole problem is that, while -1 (16 bit) = -1 (32
bit), the bit patterns are different and, to steal Rob's point: you've
got an implicit Number-Boolean conversion in the expression (in the
original code).
> Error 51
> Error 3
> Error 9
Well I expect 3 is a comment on the removal of Gosubs (hey - I've got to
admit that I used them on a VB5 project a few years back - but then I
never did buy into all this new-fangled namby-pamby improved language
crap. REAL programmers aren't afraid to sprinkle goto's & gosubs in
their code <vbg>).
9 is obviously a complaint about locking the LBound of all arrays at 0.
I'm still not sure why you've included 51 - unless it's meant as a
catch-all for everything else.
Cheers,
--
Greg
-
Re: Why integer and int32
Greg Brunet <gbrunet@semper_soft.com> wrote:
> Here's my stuff (run in VB6 SP5):
>
> ===================================
> Option Explicit
> '--------------------------------------------------
> Function CheckStatus(nBit As Integer) As Integer
> ' - dummy code to always return with bit set on
>
> If (nBit < 0) Or (nBit > 15) Then
> CheckStatus = 0
> ElseIf (nBit = 15) Then
> CheckStatus = &H8000
> Else
> CheckStatus = (2 ^ nBit)
> End If
> End Function
>
> '--------------------------------------------------
> Private Sub Form_Load()
>
> Dim BitNum As Integer
> Dim FlagSet As Long ' Integer
>
> Do
> For BitNum = 0 To 15
> FlagSet = FlagSet Or CheckStatus(BitNum)
> Next
>
> Loop Until FlagSet = &HFFFF
>
> MsgBox "We're Done", vbInformation
> End
>
> End Sub
> ===================================
>
> I ran it with FlagSet defined as both a Long and an Integer, and it
> worked both times. I also ran your code, and got an "it failed". I
> can't come up with a good reason for this apparent discrepancy, but my
> brains a bit tired right now. (Maybe VB's just being accomodating to
> both of our POV's <g>).
The difference bugged me, so I did some more testing. Put a
"Debug.Print FlagSet" statement in the For...Next loop and watch the
resulting output. The transition that occurs when setting bit 15 is
interesting: FlagSet goes from 32767 to -1! The additional high order
bits are all getting set at the same time - kewl (to quote my kids).
Cheers,
--
Greg
-
Re: Why integer and int32
On Thu, 9 May 2002 23:25:44 -0500, "Greg Brunet"
<gbrunet@semper_soft.com> wrote:
>Dan Barclay <Dan@MVPs.org> wrote:
>
>> You'd better go try it again, or show me your code. My bet is that
>> you didn't really set (only) the lower 16bits. If the lower 16bits of
>> a 32 bit FlagSet are set, your test against &HFFFF will show false in
>> VB5. Here's the code:
>>
>> Dim FlagSet As Long
>> FlagSet = &HFFFF& ' set lower 16 bits only (note force to long)
>> Debug.Print FlagSet
>> If FlagSet = &HFFFF Then
>> Debug.Print "it worked"
>> Else
>> Debug.Print "it failed"
>> End If
>
>Here's my stuff (run in VB6 SP5):
>
>===================================
>Option Explicit
>'--------------------------------------------------
>Function CheckStatus(nBit As Integer) As Integer
>' - dummy code to always return with bit set on
>
> If (nBit < 0) Or (nBit > 15) Then
> CheckStatus = 0
> ElseIf (nBit = 15) Then
> CheckStatus = &H8000
> Else
> CheckStatus = (2 ^ nBit)
> End If
>End Function
>
>'--------------------------------------------------
>Private Sub Form_Load()
>
>Dim BitNum As Integer
>Dim FlagSet As Long ' Integer
>
> Do
> For BitNum = 0 To 15
> FlagSet = FlagSet Or CheckStatus(BitNum)
> Next
>
> Loop Until FlagSet = &HFFFF
>
> MsgBox "We're Done", vbInformation
> End
>
>End Sub
>===================================
>
>I ran it with FlagSet defined as both a Long and an Integer, and it
>worked both times. I also ran your code, and got an "it failed". I
>can't come up with a good reason for this apparent discrepancy, but my
>brains a bit tired right now.
See below for the explanation.
>(Maybe VB's just being accomodating to
>both of our POV's <g>).
VB is sometimes accommodating, but it's still just code. It may not
seem like it, but it follows the same rules all the time <vbg>.
>>> My main problem was coming up with a simple CheckStatus function
>>> that could easily handle setting bit 15.
You need to take a closer look at the whole thing to understand where
the landmines are (my original point). In your code you're not just
playing with the lower 16 bits. Take a look at the CheckStatus
function when you return &H8000. It's a negative value, it gets
promoted to 32 bits since one of the operands of the Or is 32bits...
etc, etc.
>> Not a problem (or the issue), and in fact it may be data that
>> originates in hardware or from an API call.
>
>I realize that it would likely come from someplace else - I was just
>trying to come up with a simple simulation routine, and will get an
>overflow error if I don't trap for nBit=15. I'm sure that my solution
>(above), can be improved upon.
It's the whole picture (which is why a code translator misses these
things, and why humans also miss it sometimes). It not only matters
what you assign to the return function, it matters what the return
value is coerced to on return.
Again, the point is not "how can this routine be written to make it
work in both environments". The point is to show an example of what
*appears to be* fairly simpleton code that is likely to misbehave.
It's not so simple to spot, and it's not so simple to fix. Therefore,
you have to assume you need to examine all your code for stuff like
this.
Moral: Changing code behavior is a VeryBadThing.
>>> I understand that it's a
>>> number - as well as a bit pattern. My point as been that as long as
>>> you keep all the code working with in bit pattern terms (e.g., using
>>> [Loop While FlagSet <> &HFFFF]), you should be okay.
Maybe I didn't explain it clearly enough (partly on purpose
initially<g>). Let's just look at a specific case. In the Loop
expression above, FlagSet is a Long. The default size for literal
numbers is Integer. The Integer value of &HFFFF is -1.
Now, when the logical expression evaluator needs to test a Long
against an Integer it promotes the Integer to a Long. &HFFFF is -1
and as a Long it presents itself as &HFFFFFFFF.
This *should* have failed if FlagSet only had the lower 16bits set,
right? But, it had all bits set so it passed. Why did FlagSet have
all bits set?
The reason is found in expanding
FlagSet = FlagSet Or CheckStatus(BitNum)
Without going through your CheckStatus function entirely, let's look
at the case of BitNum-15. In that case CheckStatus returns -32768.
The logical expression evaluator wants both sides of the Or to be the
same size so it promotes -32768 to a Long. I think you'll find that
this sets high bits in the long.
In other words, it *looked* like your code was checking the lower 16
bits, but it was checking something else entirely and only *appeared*
to be working.
>> You would be fine so long as you programmed to known data sizes and
>> the data sizes don't change. If the data sizes change then all bets
>> are off and you'd better review your code *in detail*. See above.
>>
>> Secondly, you only have numbers to use as containers for bit patterns.
>> This isn't exactly to the point, but see
>> http://www.mvps.org/vb/tips/truth.htm . Bottom line: It's *all* in
>> the numbers.
>
>I've read your white paper (twice). I don't think that it applies here.
It always applies. It's how it works <g>. However, I didn't expand
on variable coercion (using dissimilar data types in an expression).
Remembering that "it's all in the numbers" and keeping the numbers the
same size is your key.
>I realize that we are using numbers to hold the bit patterns. My point
>continues to be (and I think is validated by the above code), that since
>you were trying to check if all 16 bits were turned on, the comparison
>to &HFFFF would do that regardless if it was in a 16 or 32 bit number.
That's exactly what you need to eliminate from your thinking. The
above code isn't doing what you think it's doing. *First* it's a
number and you figure out what the number is. Once you have the
number (and the data size) you can figure out what bits are set. The
most clear case:
MyInt = &HFFFF ' -1 ... sets all 16 bits
MyLong = &HFFFF ' -1 ... sets all 32 bits!
Again, it's *first* a number. &HFFFF is an integer number -1. OTOH,
&HFFFF& is a *long* number 65535 (note trailing &).
MyLong = &HFFFF& ' sets only lower 16 bits.
>I think that it's also much more clear for someone who is trying to pick
>up the code.
Thinking of it that way might be clear, but it's wrong!
>The whole problem is that, while -1 (16 bit) = -1 (32
>bit), the bit patterns are different and, to steal Rob's point: you've
>got an implicit Number-Boolean conversion in the expression (in the
>original code).
That's not correct. Take a look at what I've shown above and I think
you'll see the difference. It's *all* in the numbers. Forget that
Boolean is anything but a mechanism to force numbers to be 0 or -1 and
you'll save yourself some grief some day.
>> Error 51
>> Error 3
>> Error 9
>
>Well I expect 3 is a comment on the removal of Gosubs (hey - I've got to
>admit that I used them on a VB5 project a few years back - but then I
>never did buy into all this new-fangled namby-pamby improved language
>crap. REAL programmers aren't afraid to sprinkle goto's & gosubs in
>their code <vbg>).
Yup. A tool is a tool and I'm not the least embarrassed about using
any tool. Heck, I was using Basic *way* before Basic was Cool VB.
GoSub is a (code only) container. You bet your *** I used it. Delphi
has this capability as nested procedures.
>9 is obviously a complaint about locking the LBound of all arrays at 0.
Substitute "complaint" with "Microsoft Error" and you've got it.
>I'm still not sure why you've included 51 - unless it's meant as a
>catch-all for everything else.
Error 51 is the primary problem. Microsoft Internal Error.
Your other two are correct. Expanding on the Error 3, it's bad that
they didn't include GoSub... but to have reused the Return keyword is
inexcusable.
Later,
Dan
Language Stability is a *feature* I wish VB had!
(#6)
Error 51
Error 3
Error 9
....
-
Re: Why integer and int32
On Thu, 9 May 2002 23:41:15 -0500, "Greg Brunet"
<gbrunet@semper_soft.com> wrote:
>The difference bugged me, so I did some more testing.
Attaboy <g>.
>Put a
>"Debug.Print FlagSet" statement in the For...Next loop and watch the
>resulting output. The transition that occurs when setting bit 15 is
>interesting: FlagSet goes from 32767 to -1! The additional high order
>bits are all getting set at the same time - kewl (to quote my kids).
You've got it<ggg>. Like I said in the paper and a couple of times in
previous posts "it's all in the numbers". I posted a longer reply to
your previous message before seeing this one. Let me know if that
post explains it more clearly.
Later,
Dan
Language Stability is a *feature* I wish VB had!
(#6)
Error 51
Error 3
Error 9
....
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
Forum Rules
|
Top DevX Stories
Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL
|
Bookmarks