precedence of cast versus shift 
Author Message
 precedence of cast versus shift

I recently got the following line from PClint, using VC6:

#...                      ((WORD)(((DWORD)(wParam) >> 16) & 0xFFFF))
        ScrollTTYVert( hWnd, LOWORD( wParam ), HIWORD( wParam ) ) ;
dvcom.c(572) : Warning 572: Excessive shift value (precision 16 shifted
right by 16)

where lint is showing preprocessed line, source line, problem.

What is the actual operator precedence.  Obviously the writer (MicroS)
of the system macros LOWORD and HIWORD thought that (DWORD)(wParam)
would be evaluated before >> 16.  I suspect that is wrong, but a quick
scan of the 99 draft std. doesn't tell me.

Either lint is wrong or Microsoft is wrong.  Guess which I am betting
on!  Except that this seems to be a very common idiom in Windows, so
how come it hasn't blown up before?

--

  http://www.*-*-*.com/
--



Sun, 02 Mar 2003 22:13:25 GMT  
 precedence of cast versus shift

Quote:

> I recently got the following line from PClint, using VC6:

> #...                      ((WORD)(((DWORD)(wParam) >> 16) & 0xFFFF))
>         ScrollTTYVert( hWnd, LOWORD( wParam ), HIWORD( wParam ) ) ;
> dvcom.c(572) : Warning 572: Excessive shift value (precision 16 shifted
> right by 16)

> where lint is showing preprocessed line, source line, problem.

> What is the actual operator precedence.  Obviously the writer (MicroS)
> of the system macros LOWORD and HIWORD thought that (DWORD)(wParam)
> would be evaluated before >> 16.  I suspect that is wrong, but a quick
> scan of the 99 draft std. doesn't tell me.

> Either lint is wrong or Microsoft is wrong.  Guess which I am betting
> on!  Except that this seems to be a very common idiom in Windows, so
> how come it hasn't blown up before?

Lint has not said that it is wrong, it is a warning. It can mean that
the code is pointless as it always produces zero. If wParam is an
unsigned 16 bit value then this will be the so even when the cast is
applied before the shift as it should be. Lint is probably sufficiently
well designed to detect this.

Malcolm Kay
--



Mon, 03 Mar 2003 03:00:00 GMT  
 precedence of cast versus shift

Quote:

> I recently got the following line from PClint, using VC6:

> #...                      ((WORD)(((DWORD)(wParam) >> 16) & 0xFFFF))
>         ScrollTTYVert( hWnd, LOWORD( wParam ), HIWORD( wParam ) ) ;
> dvcom.c(572) : Warning 572: Excessive shift value (precision 16
shifted
> right by 16)

> where lint is showing preprocessed line, source line, problem.

> What is the actual operator precedence.  Obviously the writer (MicroS)
> of the system macros LOWORD and HIWORD thought that (DWORD)(wParam)
> would be evaluated before >> 16.  I suspect that is wrong, but a quick
> scan of the 99 draft std. doesn't tell me.

> Either lint is wrong or Microsoft is wrong.  Guess which I am betting
> on!  Except that this seems to be a very common idiom in Windows, so
> how come it hasn't blown up before?

Taking a quick look at my K&R tells me that the cast does indeed have
higher precendence than the shift. It does look as if the problem is
with PCLint.

Quote:
> --

>  http://www.qwikpages.com/backstreets/cbfalconer/
> --


--
Tristan Styles #1485

Failure is not an Option
It is Standard Operating Procedure
--



Mon, 03 Mar 2003 03:00:00 GMT  
 precedence of cast versus shift


Quote:
>I recently got the following line from PClint, using VC6:

>#...                      ((WORD)(((DWORD)(wParam) >> 16) & 0xFFFF))
>        ScrollTTYVert( hWnd, LOWORD( wParam ), HIWORD( wParam ) ) ;
>dvcom.c(572) : Warning 572: Excessive shift value (precision 16 shifted
>right by 16)

It could simply be that your lint doesn't understand what a DWORD is.

That is to say, lint might be processing some header file which does something
like

        #define DWORD unsigned int

or

        typedef unsigned int DWORD;

Then if lint pretends that unsigned int is 16 bits wide, it would explain why
it produces the diagnostic. An unsigned int *can* be as narrow as 16 bits.
The other explanation---namely that its expression parser has a glaring
error---is a little hard to believe.  Shift expressions are several levels
below cast expressions on the precedence scale.

--
Any hyperlinks appearing in this article were inserted by the unscrupulous
operators of a Usenet-to-web gateway, without obtaining the proper permission
of the author, who does not endorse any of the linked-to products or services.
--



Mon, 03 Mar 2003 03:00:00 GMT  
 precedence of cast versus shift

Quote:

> I recently got the following line from PClint, using VC6:

> #...                      ((WORD)(((DWORD)(wParam) >> 16) & 0xFFFF))
>         ScrollTTYVert( hWnd, LOWORD( wParam ), HIWORD( wParam ) ) ;
> dvcom.c(572) : Warning 572: Excessive shift value (precision 16
shifted
> right by 16)

> where lint is showing preprocessed line, source line, problem.

> What is the actual operator precedence.  Obviously the writer (MicroS)
> of the system macros LOWORD and HIWORD thought that (DWORD)(wParam)
> would be evaluated before >> 16.  I suspect that is wrong, but a quick
> scan of the 99 draft std. doesn't tell me.

> Either lint is wrong or Microsoft is wrong.  Guess which I am betting
> on!  Except that this seems to be a very common idiom in Windows, so
> how come it hasn't blown up before?

Casts have higher precedence than shift operators; the grammar
indicates the precedence of operators, and they are also listed
in the draft standard from highest precedence to lowest.  On the
other hand, casting a 16 bit value to a 32 bit value and then
shifting it 16 bits right doesn't seem particularly useful, so
it may be that lint kept track of the ancestry of the 32 bit
value.  It is only a warning, after all.  I don't know why
it hasn't blown up before; perhaps it's also a common idiom
in Windows to compile with most warnings suppressed.

--
MJSR
--



Mon, 03 Mar 2003 03:00:00 GMT  
 precedence of cast versus shift

Quote:

> I recently got the following line from PClint, using VC6:
> #...                      ((WORD)(((DWORD)(wParam) >> 16) & 0xFFFF))
>         ScrollTTYVert( hWnd, LOWORD( wParam ), HIWORD( wParam ) ) ;
> dvcom.c(572) : Warning 572: Excessive shift value (precision 16 shifted
> right by 16)
> where lint is showing preprocessed line, source line, problem.
> What is the actual operator precedence.

Casts do have a higher priority than the >> operator, so the HIWORD
macro is implemented correctly, here. That's not what the error is
about.

Quote:
> Either lint is wrong or Microsoft is wrong.  

[Why should they not both be wrong?...]

Actually, they're both right. The user code is doing something
arguably stupid, here (extracting the 'high word' out of a word-typed
variable like 'wParam' is a useless exercise: it's always zero), and
your 'lint' was clever enough to detect it.

If this is a commonly seen construct, it may be meant for some other
platform (16bit vs. 32bit Windows code), where the same warning would
not occur, because types are defined differently.

[All this based on the assumption that I remember the usual type of a
'wParam' in Windows programming correctly. I don't have my Petzold at
hand to check it.]
--

Even if all the snow were burnt, ashes would remain.
--



Mon, 03 Mar 2003 03:00:00 GMT  
 precedence of cast versus shift

says...

[ ... in: ]

Quote:
> #...                      ((WORD)(((DWORD)(wParam) >> 16) & 0xFFFF))

[ ... ]

Quote:
> What is the actual operator precedence.  Obviously the writer (MicroS)
> of the system macros LOWORD and HIWORD thought that (DWORD)(wParam)
> would be evaluated before >> 16.  I suspect that is wrong, but a quick
> scan of the 99 draft std. doesn't tell me.

The cast has higher precedence.  Technically speaking, the standard
doesn't give anything in terms of "precedence" as such, which is why
a quick scan didn't tell you.

What you have to do is look at the grammar.  Though it's only
informative, appendix A2 is basically a consolidated listing of the
pieces of grammar from throughout the body of the standard.  If you
want to figure out precedence, it's generally where you want to look.

A ``cast-expression'' is defined in section 6.5.4. A cast-expression
is one of the operands of a ``multiplicative-expression'' (6.5.5).  
This is an operand in an ``additive-expression'' (6.5.6), which in
turn is an operand in a ``shift-expression'' (6.5.7).

That means that casting has considerably higher precedence than
shifting.  Note that these definitions are in descending order of
precedence; you can usually determine precedence simply by looking at
relative positions in the table of contents.

Note that your wording above may be a bit misleading though:
precedence does NOT necessarily affect order of evaluation as such.  
As I'm sure you're well aware, the actual order of evaluation is
governed only by sequence points.

--
    Later,
    Jerry.

The Universe is a figment of its own imagination.
--



Mon, 03 Mar 2003 03:00:00 GMT  
 precedence of cast versus shift

Quote:

> What is the actual operator precedence.  Obviously the writer (MicroS)
> of the system macros LOWORD and HIWORD thought that (DWORD)(wParam)
> would be evaluated before >> 16.  I suspect that is wrong, but a quick
> scan of the 99 draft std. doesn't tell me.

The cast happens first.  See the definitions of shift-expr,
additive-expr, multiplicative-expr and cast-expr.

Perhaps lint noticed that the value of (DWORD)(wParam) fits in 16
bits even though the type has 32 bits.  That would make the shift
suspicious, because the result is always 0.

Why is wParam a 16-bit value in the first place?  IIRC, it should
be 32-bit if you're programming for Win32.
--



Mon, 03 Mar 2003 03:00:00 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. precedence of cast versus shift

2. Shift/reduce conflicts and precedence

3. C code check : SPLINT versus PC-LINT versus QA/C versus POLYSPACE versus PURIFY

4. Bit shifting versus struct packing performance

5. order of precedence for cast

6. Casting and Left Shifting

7. Left Shift Key OR Right Shift key is pressed

8. ASCII shift out and shift in char.

9. Data Access Performance of XML, versus SQL versus Text File

10. old style casts vs new style casts

11. casting of struct element void pointer casting

12. Cast...always cast...

 

 
Powered by phpBB® Forum Software