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 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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 #include 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