delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2001/04/10/00:32:03

From: Jack Klein <jackklein AT spamcop DOT net>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: GCC 2.95.3 and C standard(s) + commandline switch problems
Message-ID: <s015dt833n0o8k9r5f3odchi4dd7ic8bog@4ax.com>
References: <4830 DOT 986817066 AT www1 DOT gmx DOT net>
X-Newsreader: Forte Agent 1.8/32.548
MIME-Version: 1.0
Lines: 116
Date: Tue, 10 Apr 2001 04:16:56 GMT
NNTP-Posting-Host: 12.75.153.87
X-Complaints-To: abuse AT worldnet DOT att DOT net
X-Trace: bgtnsc07-news.ops.worldnet.att.net 986876216 12.75.153.87 (Tue, 10 Apr 2001 04:16:56 GMT)
NNTP-Posting-Date: Tue, 10 Apr 2001 04:16:56 GMT
Organization: AT&T Worldnet
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

On Mon, 9 Apr 2001 13:51:06 +0200 (MEST), ahelm AT gmx DOT net wrote in
comp.os.msdos.djgpp:

> Hi 
> I'm having troubles with a subtle ANSI C standard problem
> and maybe some bugs in the DJGPP port of GCC (commandline switches).
> 
> What type is the result of the multiplication of two unsigned short
> variables?

There are exactly three possibilities:

1. unsigned int if USHRT_MAX > INT_MAX, as both unsigned shorts are
converted to unsigned ints prior to the multiplication.  This was and
still is the case on many compilers for 8 and 16 bit processors, where
short and int share the same 16 bit representation.

2. signed int if USHRT_MAX < INT_MAX, as both unsigned shorts are
converted to signed ints prior to the multiplication.  This is the
case on many common compilers for 32 bit platforms where int has 32
bits and short 16 bits, including x86 gcc.

3. undefined if USHRT_MAX < INT_MAX < USHRT_MAX * USHRT_MAX and the
product of the two unsigned shorts is greater than INT_MAX, as both
unsigned shorts are converted to signed ints prior to the
multiplication and arithmetic overflow of signed integer types results
in undefined behavior.

> The problem is that there is a difference between old and new ANSI
> standard.

No, there is not.

> ANSI C (both standards) clearly state that the result of a binary
> arithmetic operation is of the same type as the inputs after
> applying the "usual arithmetic conversions" (to the inputs) when
> necessary.
> 
> Following the rules in 6.2.1.5 in the old standard
> (usual arithmetic conversions), none of the rules apply
> until reaching the last:
> "Otherwise both operands have type int"

You are missing the application of the fourth paragraph at the first
level of indentation under 6.2.1.5:

            Otherwise, the integer promotions are performed on both
            operands.   Then the following rules are applied to the
            promoted operands:

The result of the integer promotion rules is never anything smaller
than an int.  The integer promotion rules themselves are described in
6.2.1.1. in C90 and 6.3.1.1 in C99.

> So both operands are converted to int before multiplication.
> That explains the int (32bit) result of a 16x16bit multiplication
> when using GCC. Because actually 
> (16bit -> 32bit) x (16bit -> 32bit) = 32bit 
> is computed
> 
> The new standard however has a new rule in the "Ususal 
> arithmetic conversions":
> 
> "If both operands have the same type, then no further conversion 
> is needed."

Yes, but this immediately follows the paragraph:

            Otherwise, the integer promotions are performed on both
            operands.   Then the following rules are applied to the
            promoted operands:

In fact this text is cut and pasted from a formatted copy of C99 that
I have, but the wording is exactly identical to C89/C90.

> And 6.2.5 (new standard) or 6.1.2.5 (old standard):
                              ^^^^^^^
ITYM 6.2.1.5 again here.

> "A computation involving unsigned operands can never overflow,
> because a result that cannot be represented by the resulting 
> unsigned integer type is reduced modulo the number that is 
> one greater than the largest value that can be represented 
> by the resulting type."
> 
> This clearly defines the overflow behaviour of unsigned 
> operations.

	[snip]

There are very, very few things that you can do in C with an object of
a type smaller than int without promoting it to int in the process.
Prior to C89 and function prototypes you could assign a type smaller
than int to another type also smaller than int, the same or a
different type.  While this might require a conversion, it would not
necessarily be a conversion "all the way" to int.  With the advent of
function prototypes you can also pass a type smaller than int to a
function or return a type smaller than int from a function that is so
prototyped.

In any arithmetic, bit-wise, shift, or logical expression containing
the value of an object smaller than int, this value is promoted to at
least signed or unsigned int per the promotion rules.  Specifically in
the abstract machine no operator other than sizeof is ever applied to
a value of a type smaller than int.  Of course the implementation can
sometimes optimize the actual conversion away under the as-if rule.

	[posted & mailed]

-- 
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019