delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2001/04/09/07:51:25

From: ahelm AT gmx DOT net
Date: Mon, 9 Apr 2001 13:51:06 +0200 (MEST)
To: djgpp AT delorie DOT com
MIME-Version: 1.0
Subject: GCC 2.95.3 and C standard(s) + commandline switch problems
X-Authenticated-Sender: #0003579562 AT gmx DOT net
X-Authenticated-IP: [194.201.128.4]
Message-ID: <4830.986817066@www1.gmx.net>
X-Mailer: WWW-Mail 1.5 (Global Message Exchange)
X-Flags: 0001
Reply-To: djgpp AT delorie DOT com

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?

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

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"

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."

And 6.2.5 (new standard) or 6.1.2.5 (old standard):

"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.

This would mean that the result of a multiplication
of two unsigned short is again an unsigned short or
16bit x 16bit = 16bit

So using the following testcode we should see a difference in 
results when switching between standards:

#include <stdio.h>
#include <limits.h>

int main()
{
  unsigned short a = 12345, b = 23456;
  unsigned long x, y, z;


  x = a*b;                   /* unsigned short test */
  y = (unsigned long)a * b;  /* 32x32 reference     */
  z = y%(USHRT_MAX+1);       /* 16x16 reference     */

  printf("%lu %lu %lu\n", x, y, z);

  return 0;
}

Compling this for the different standards with GCC 2.95.3 
doesn't show any differences.


GCC 2.95.3 also seems to have problems with the commandline switches:

The -fstd= switches don't seem to work:

(part of the screen output using -v)
cc1.exe: Invalid option `-fstd=c89'
GNU C version 2.95.3 20010315/djgpp (release) (djgpp) compiled by GNU C
version
2.95.3 20010315/djgpp (release).

The gcc info pages are somewhat confusing here but -std= seems to be
accepted. Although you can write anything behind the = sign without
warning (and without any noticable change in behaviour. E.g.: -std=c123
I've tried all the dialects like -std=c89 -std=c9x (also the long forms).

Some other commandline switch troubles:
C:\USERS\C>gcc -Wall -ansi -std=c89 -O2 x.c -o x.exe
x.c:0: malformed option `-D __STRICT_ANSI__-trigraphs'

I know these two switches should do the same thing, but 
anyway they shouldn't concatenate in the intermediate representation
without whitespace.

That's all for now ;-)

Plesae CC your replies to my email address: ahelm AT gmx DOT net

Regards,

Tony






-- 
__________________________
Anton Helm
Farnborough, Hampshire, UK
mailto:ahelm AT gmx DOT net
phoneto:+44-1252-867200

Sent through GMX FreeMail - http://www.gmx.net

- Raw text -


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