LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-11-2007, 07:32 PM   #1
_john_i_
Member
 
Registered: Aug 2003
Location: Austin, TX
Distribution: Linux from Scratch
Posts: 52

Rep: Reputation: 15
Assigning a short to a double. Differences between gcc-2.95 and gcc-3.4.x


Ok, I'm not sure if this is a bug or a feature.....

In gcc-2.95 (and several non-gnu c compilers I tried) if you assign a double precision floating point value to a signed short, where the double value is > 32767, it acts exactly the same as assigning an integer that is >32767 to the short. It wraps the short around to the appropriate negative value.

Code:
double d;
short i;

d=33600;
i=d;
printf("i=%d\n",i);
Produces:

i=-31936


This is what I consider "correct".

If you do the same thing with gcc-3.4.x or gcc-4.1.x, the code produces:

i=-32768;

I found two ways of making it produce the value I expect. The first is to change the code to cast the destination to an unsigned short:

Code:
double d;
short i;

d=33600;
i=(unsigned short)d;
printf("i=%d\n",i);
That produces:
i=-31936 like the original code did.

The other way I found to make it work like gcc-2.95 is to tell the compiler to use sse2 instructions for the floats:

gcc assign.c -msse2 -mfpmath=sse -o assign

Strange that pumping it through SSE2 assembly code makes it work like the original. Of course older processors don't have SSE2.


Looking at the assembly code produced by the compilers:
Code:
GCC-2.95             GCC-3.3.4
fldl -8(%ebp)        fldl -8(%ebp)
fnstcw -12(%ebp)     fnstcw -12(%ebp)
movw -12(%ebp),%dx   movl -12(%ebp), %eax
orw $3072,%dx        movb $12, %ah
movw %dx,-14(%ebp)   movw %ax, -14(%ebp)
fldcw -14(%ebp)      fldcw -14(%ebp)
fistpl -20(%ebp)     fistps -10(%ebp)
movl -20(%ebp),%eax  fldcw -12(%ebp)
fldcw -12(%ebp)
Where I think the main difference is is the use of the fistpl instruction in gcc-2.95, which would copy the contents of a floating point register into memory as a long int. gcc-3.3.4 uses fistps for copying a short. Using the typecast method, gcc-3.3.4 uses fistpl as well.


I guess my big question is: What is really the correct behavior? I thought perhaps a c standard changed where the semantics of this type of assignment changed, but if it works the other way when compiling in SSE2 support, maybe not.

Does anyone have any ideas?


John
 
Old 01-12-2007, 04:43 AM   #2
vladmihaisima
Member
 
Registered: Oct 2002
Location: Delft, Netherlands
Distribution: Gentoo
Posts: 196

Rep: Reputation: 33
From ISO/IEC 9899:1999 paragraph 6.3.1.4:

Quote:
When a finite value of real floating type is converted to an integer type other than _Bool,
the fractional part is discarded (i.e., the value is truncated toward zero). If the value of
the integral part cannot be represented by the integer type, the behavior is undefined.
From what I understand from that, gcc-s behaviors are both 'correct' from the point of view of the standard.

There are many 'undefined' things in the standard, many of them related to things similar to overflow (like you case). There is also a possible reason: to be able to implement C on a wide types of architectures, without a big performance degradation. For example there are architectures that 'saturate' when you add two integers (and you will obtain INT_MAX + 1 = INT_MAX). So the standard specifies that signed integer overflow is undefined. (at least the unsigned overflow is defined to wrapping around).
 
Old 01-12-2007, 01:11 PM   #3
_john_i_
Member
 
Registered: Aug 2003
Location: Austin, TX
Distribution: Linux from Scratch
Posts: 52

Original Poster
Rep: Reputation: 15
Thanks for the explanation and reference to the standard.

That certainly explains why it is happening inconsistantly between compilers.

Now I just need search through a ton of old legacy code we have here. We have some stuff that relys on signed short wraparound, and we do have quite a few instances of assigning floating point numbers to these.


John
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
have gcc compilation error during gcc installtion in linuxfromscratch vbshanmugaprakash Linux - General 3 12-13-2006 05:52 AM
LXer: Tools: GCC 3.4.6, Final GCC 3 Release LXer Syndicated Linux News 0 05-30-2006 02:21 AM
gcc wont install, 'failed dependencies: glibc-devel is needed by gcc-3.3.3-41' TdlSnare SUSE / openSUSE 3 11-29-2004 02:13 PM
gcc 3.3.1 configure: unable to determine size of short disciple061 Linux - Software 0 12-08-2003 03:52 PM
export CC=/usr/bin/gcc-3.2 - switch gcc version? ferreter Linux - Software 1 08-20-2003 12:07 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 12:01 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration