On Fri, Sep 19, 2008 at 5:03 PM, Andriy Gapon <[EMAIL PROTECTED]> wrote:
>
> There is a very simple function:
> /******** func.c **********/
> #include <netinet/in.h>
>
> uint16_t my_htons(uint16_t hostshort)
> {
>        return htons(hostshort);
> }
> /**************************/
>
> $ cc func.c -Wconversion -Werror -c -o func.o
> Exit 0
>
> $ cc func.c -O1 -Wconversion -Werror -c -o func.o
> cc1: warnings being treated as errors
> func.c: In function 'my_htons':
> func.c:5: error: conversion to 'short unsigned int' from 'int' may alter its
> value
> Exit 1
>
> Adding -E flag I get the following code:
> ...
> # 2 "func.c" 2
>
> uint16_t my_htons(uint16_t hostshort)
> {
>  return (__extension__ ({ register unsigned short int __v, __x =
> (hostshort); if (__builtin_constant_p (__x)) __v = ((((__x) >> 8) & 0xff) |
> (((__x) & 0xff) << 8)); else __asm__ ("rorw $8, %w0" : "=r" (__v) : "0"
> (__x) : "cc"); __v; }));

The computation ((((__x) >> 8) & 0xff) |  (((__x) & 0xff) << 8)) is promoted
to int as of C language standards rules and the store to __v truncates it.

The warning isn't clever enough to see that this doesn't happen due to
the masking applied, and in general there are always cases that would
slip through.

Richard.

Reply via email to