#3794: Complier warnings on OS X 10.11.1 with Xcode 7.1.1
---------------------+---------------------
  Reporter:  chdiza  |      Owner:  brendan
      Type:  defect  |     Status:  new
  Priority:  minor   |  Milestone:
 Component:  SMTP    |    Version:
Resolution:          |   Keywords:
---------------------+---------------------

Comment (by vinc17):

 Replying to [comment:11 code@…]:
 > {{{
 > A char is signed on every platform.
 > }}}

 No, a {{{char}}} is '''not''' signed on every platform. This is
 implementation-defined. On Power PC, {{{char}}} is unsigned.

 > {{{
 > This is not a harmless warning, IT IS A BUG.
 > }}}

 If you mean that the warning is a bug, yes. Note that the initial code
 ({{{*a > 0 && *a < 128}}}) was correct whether {{{char}}} is signed or
 not.

 > {{{
 > This is illustrated by the following tiny program:
 >
 > #include <stdio.h>
 > int main(int argc, char **argv)
 > {
 >     char x;
 >     x = 128;
 >     printf("%d\n", (int)x);
 >     return 0;
 > }
 >
 > On any sane platform, this will print -128, not 128.
 > }}}

 If {{{char}}} is unsigned, it will print 128. If {{{char}}} is signed, the
 result is implementation-defined because in such a case, 128 is not
 representable in a {{{char}}} (assuming {{{CHAR_BIT = 8}}}).

 > {{{
 > That's because the value of x is, in fact, -128; the compiler has
 performed an
 > implicit cast
 > }}}

 The correct term is "conversion" (a cast is an explicit conversion).

 > {{{
 > Vincent's proposed fix is technically correct, but is pretty
 > unreadable, possibly obscuring the intent to the reader.
 > }}}

 My proposal was just based on Kevin's in [comment:7]. I forgot that the
 conversion to {{{unsigned char}}} made the comparison with 128 possible
 again (the first intent of this conversion was just to fix Kevin's code).

 > {{{
 > A better fix
 > that retains the intent would have been (almost) what Petr suggested,
 > except he had the sign wrong, and there's no longer any reason to
 > compare to 0, since unsigned chars can never be negative:
 > }}}

 You still need to reject the value 0.

 > {{{
 >     while (a && *((unsigned char *)a) < 128)
 > }}}

 This should be
 {{{
     while (*((unsigned char *)a) && *((unsigned char *)a) < 128)
 }}}

 > {{{
 > However, if you're going to be comparing chars to numeric literal
 > ASCII codes, you should really consider whether the data should
 > actually be unsigned char instead of just char.  The main reason NOT
 > to do that is if you have to use it with old POSIX API calls that got
 > the sign wrong, expectng a signed char* rather than an unsigned char*,
 > }}}

 I don't think any POSIX API expects a {{{signed char*}}}.

 > {{{
 > of which there are a number (like strcmp() et al.).
 > }}}

 No, that's just {{{char *}}}. {{{char}}} and {{{signed char}}} are not
 compatible types, even when {{{char}}} is signed.

-- 
Ticket URL: <http://dev.mutt.org/trac/ticket/3794#comment:14>
Mutt <http://www.mutt.org/>
The Mutt mail user agent

Reply via email to