473,468 Members | 1,369 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

0x400000*3/0x40000 undefined ?

A true story: one C compiler for an embedded processor that
I use claims " ANSI '89 compatibility ". But when I upgraded
from version 2.30 to 2.30.01, some previously working code
misbehaved. After reduction, it turns out that for

unsigned char foo = 0x400000*3/0x40000;

the former compiler set foo to 0x30, and the later 0xF0.

All versions of the compiler agree on
foo = 0x400000*3L/0x40000; /* 0x30 */
foo = 0xC00000/0x40000; /* 0x30 */
foo = 0x400000*3>>18; /* 0x30 */
foo = 0x40000*3/0x4000; /* 0x30 */

The outcome of <limits.h> is that
INT_MAX is 32767
LONG_MAX is 0x7fffffff
but it turns out the compiler has a an extra non-standard
"short long" integer type, and
SLONG_MAX is 0x7fffff

Is the newer compiler wrong ?
Francois Grieu
Nov 14 '05 #1
7 2457
Francois Grieu <fg****@francenet.fr> writes:
A true story: one C compiler for an embedded processor that
I use claims " ANSI '89 compatibility ". But when I upgraded
from version 2.30 to 2.30.01, some previously working code
misbehaved. After reduction, it turns out that for

unsigned char foo = 0x400000*3/0x40000;

the former compiler set foo to 0x30, and the later 0xF0.

All versions of the compiler agree on
foo = 0x400000*3L/0x40000; /* 0x30 */
foo = 0xC00000/0x40000; /* 0x30 */
foo = 0x400000*3>>18; /* 0x30 */
foo = 0x40000*3/0x4000; /* 0x30 */

The outcome of <limits.h> is that
INT_MAX is 32767
LONG_MAX is 0x7fffffff
but it turns out the compiler has a an extra non-standard
"short long" integer type, and
SLONG_MAX is 0x7fffff

Is the newer compiler wrong ?


Yes, I believe it is.

Adding a "short long" type should be ok, since it can only be used by
a program that would be illegal in strict ANSI mode.

Adding SLONG_MAX to <limits.h> is non-conforming, but it's not going
to be a problem unless the user program tries to define that
identifier for itself.

But I think the real problem is that it treats the hex constants as
being of type "short long".

The type of a hex constant is the first of
int
unsigned int
long
unsigned long
in which its value will fit (C99 adds long long and unsigned long
long). In this case, both 0x400000 and 0x40000 should be of type
long. Apparently the compiler chooses to treat them as constants of
type "short long", which would make perfect sense if "short long" were
part of the language.

On the other hand, the declaration

unsigned char foo = 0x400000*3/0x40000;

is non-portable, and would legitimately yield the same result if
INT_MAX were 0x7fffff. It might be better to specify the types
explicitly:

unsigned char foo = 0x400000UL*3/0x40000UL;

or simply:

unsigned char foo = 0x30;

if that's what you want. (The latter probably doesn't apply, since
you said it was the result of reducing the actual code.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #2
Francois Grieu wrote:

A true story: one C compiler for an embedded processor that
I use claims " ANSI '89 compatibility ". But when I upgraded
from version 2.30 to 2.30.01, some previously working code
misbehaved. After reduction, it turns out that for

unsigned char foo = 0x400000*3/0x40000;

the former compiler set foo to 0x30, and the later 0xF0.

All versions of the compiler agree on
foo = 0x400000*3L/0x40000; /* 0x30 */
foo = 0xC00000/0x40000; /* 0x30 */
foo = 0x400000*3>>18; /* 0x30 */
foo = 0x40000*3/0x4000; /* 0x30 */

The outcome of <limits.h> is that
INT_MAX is 32767
LONG_MAX is 0x7fffffff
but it turns out the compiler has a an extra non-standard
"short long" integer type, and
SLONG_MAX is 0x7fffff

Is the newer compiler wrong ?


Yes, it is broken. However you can and should have simply used 3L
in the original expression. Without checking limits.h you have no
idea what type 0x400000 actually is.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #3
Francois Grieu wrote:
A true story: one C compiler for an embedded processor that
I use claims " ANSI '89 compatibility ". But when I upgraded
from version 2.30 to 2.30.01, some previously working code
misbehaved. After reduction, it turns out that for

unsigned char foo = 0x400000*3/0x40000;

the former compiler set foo to 0x30, and the later 0xF0.

All versions of the compiler agree on
foo = 0x400000*3L/0x40000; /* 0x30 */
foo = 0xC00000/0x40000; /* 0x30 */
foo = 0x400000*3>>18; /* 0x30 */
foo = 0x40000*3/0x4000; /* 0x30 */

The outcome of <limits.h> is that
INT_MAX is 32767
LONG_MAX is 0x7fffffff
but it turns out the compiler has a an extra non-standard
"short long" integer type, and
SLONG_MAX is 0x7fffff

Clearly this compiler is treating 0x400000 as a SLONG
which then overflows when you multiply it by 3
(probably giving you a negative number).
Is the newer compiler wrong ?


Obviously. You should disable this slong extension,
unless you really need the optimisation .
You could also avoid troubles by labelling your long
constants as long: 0x400000L * 3 / 0x40000
Some compilers can display a warning if you use a long
constant without specifying the L suffix etc.

Ideally there would be a compiler switch to disable it
for unadorned integer constants and integer promotions,
but allow you to explicity specify a 'slong' . That
way, ANSI compliant code could still be compiled. I am
afraid that if there is no switch then you will have to
review all of your code for integer promotions to slong.

Nov 14 '05 #4
In article <fg**************************@individual.net>,
Francois Grieu <fg****@francenet.fr> wrote:
A true story: one C compiler for an embedded processor that
I use claims " ANSI '89 compatibility ". But when I upgraded
from version 2.30 to 2.30.01, some previously working code
misbehaved. After reduction, it turns out that for

unsigned char foo = 0x400000*3/0x40000;

the former compiler set foo to 0x30, and the later 0xF0.

All versions of the compiler agree on
foo = 0x400000*3L/0x40000; /* 0x30 */
foo = 0xC00000/0x40000; /* 0x30 */
foo = 0x400000*3>>18; /* 0x30 */
foo = 0x40000*3/0x4000; /* 0x30 */

The outcome of <limits.h> is that
INT_MAX is 32767
LONG_MAX is 0x7fffffff
but it turns out the compiler has a an extra non-standard
"short long" integer type, and
SLONG_MAX is 0x7fffff

Is the newer compiler wrong ?


It seems that you use a compiler for a language that is similar to C,
but not equal to C. I would say that your compiler is right, but it is
not a C compiler :-(

(Obviously a completely conforming compiler that used 24 bit int's could
also give the results that you found, so the code was never 100%
portable in the first place).
Nov 14 '05 #5
Francois Grieu wrote:
A true story: one C compiler for an embedded processor that
I use claims " ANSI '89 compatibility ". But when I upgraded
from version 2.30 to 2.30.01, some previously working code
misbehaved. After reduction, it turns out that for

unsigned char foo = 0x400000*3/0x40000;
This in itself is not strictly conforming.

the former compiler set foo to 0x30, and the later 0xF0.

All versions of the compiler agree on
foo = 0x400000*3L/0x40000; /* 0x30 */
foo = 0xC00000/0x40000; /* 0x30 */
foo = 0x400000*3>>18; /* 0x30 */
foo = 0x40000*3/0x4000; /* 0x30 */


Other replies notwithstanding, the first alternative above is better
than the original.

Your original code can still fail on genuine conforming compilers since
0x400000 may be an int, but 0x400000*3 may (theoretically) overflow. By
forcing the use of longs (or unsigned longs) you give strict
conformance to your code (for the given constants.)

--
Peter

Nov 14 '05 #6
On Wed, 05 Jan 2005 22:40:30 +0000, Christian Bau
<ch***********@cbau.freeserve.co.uk> wrote in comp.lang.c:
In article <fg**************************@individual.net>,
Francois Grieu <fg****@francenet.fr> wrote:
A true story: one C compiler for an embedded processor that
I use claims " ANSI '89 compatibility ". But when I upgraded
from version 2.30 to 2.30.01, some previously working code
misbehaved. After reduction, it turns out that for

unsigned char foo = 0x400000*3/0x40000;

the former compiler set foo to 0x30, and the later 0xF0.

All versions of the compiler agree on
foo = 0x400000*3L/0x40000; /* 0x30 */
foo = 0xC00000/0x40000; /* 0x30 */
foo = 0x400000*3>>18; /* 0x30 */
foo = 0x40000*3/0x4000; /* 0x30 */

The outcome of <limits.h> is that
INT_MAX is 32767
LONG_MAX is 0x7fffffff
but it turns out the compiler has a an extra non-standard
"short long" integer type, and
SLONG_MAX is 0x7fffff

Is the newer compiler wrong ?


It seems that you use a compiler for a language that is similar to C,
but not equal to C. I would say that your compiler is right, but it is
not a C compiler :-(

(Obviously a completely conforming compiler that used 24 bit int's could
also give the results that you found, so the code was never 100%
portable in the first place).


Yes, and there were (and probably still are) such compilers for the
Motorola 56xxx series of Digital Signal Processors. The original
members of the family had 24-bit registers, 24-bit ints, and 48-bit
longs.

--
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++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #7
Thanks for all the comments. I agree with most, and especially
with Christian Bau's
I would say that your compiler is right, but it is
not a C compiler :-(

François Grieu
Nov 14 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: RU | last post by:
Hi, I am working on a porting project to port C/C++ application from unixware C++, AT&T Standard components to g++ with STL on Linux. This application has been working properly on...
1
by: Stu | last post by:
I am trying to build the xerces shared library with 2.3.0 version of their source code on an AIX 5.1 32 bit machine with the following version of the g++ compiler /usr/local/bin/g++ -v Reading...
4
by: Mike | last post by:
I am having a problem when a field is spaces being undefined. I wasn't sure if the problem was Excel or Javascript, so I thought I would post here first. The users are able to select from a drop...
1
by: Codemutant | last post by:
**** Post for FREE via your newsreader at post.usenet.com **** I just cannot find what is undefined in this code.
1
by: Foolster41 | last post by:
I'm rather new to C++ programing. I'm using the dev-C++ program on a windows XP OS. I'm trying to compile the code for a multi user dungeon (MUD) called circle-mud. When I compile I get the...
13
by: Don Vaillancourt | last post by:
What's going on with Javascript. At the beginning there was the "undefined" value which represented an object which really didn't exist then came the null keyword. But yesterday I stumbled...
49
by: matty | last post by:
Hi, I recently got very confused (well that's my life) about the "undefined" value. I looked in the FAQ and didn't see anything about it. On...
3
by: Michael Sgier | last post by:
Hi i get thousands of messages like below. How shall i resolve that? Thanks Mcihael Release/src/Utility/RawImage.o: In function `CMaskImage::CMaskImage(int, int, char const*)':...
45
by: VK | last post by:
(see the post by ASM in the original thread; can be seen at <http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/3716384d8bfa1b0b> as an option) As that is not in relevance to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.