Mail Archives: djgpp/2001/04/09/07:51:25
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 -