Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[xpost] a new C/C++ type that when overflow i see it

2 views
Skip to first unread message

柑\/b

unread,
Aug 9, 2007, 3:09:19 PM8/9/07
to
this would be an example for using nasm and a c++ compiler all
together (for doing a 32 bits type that overflow if something goes
wrong)

using assembly and c++ has some disadvantage (because compiler has to
use all the same operation for doing something (that i should
reproduce in assembly))
then i not understand many function that compiler use in the code
(that i not add)

but all this has the vantage of reduce written text code
and if you have to write something that use the structure of type
"ou32" you have to write more than me

then i would say that type "ou32" is better of your beloved size_t
that all you use in malloc and all the routines that has to deal with
arrays

not because is more fast but because it has the controll on overflow
that size_t can not to have

can you please point out to some error do you see below?
what do you think on it?

thank you
-----------------------------------
; nasm file of name "nasmfile.asm"
; nasmw -fobj nasmfile.asm

section _DATA public align=4 class=DATA use32

align 16 , db 0
ffffffff dt 4294967295.0
fake dt 0.0
offffffff dq 4294967295.0

global @$badd$q4ou32t1 , @$bsub$q4ou32t1 , @$bmul$q4ou32t1
global @$bdiv$q4ou32t1 , @ou32@$bctr$qv , @ou32@$bctr$qi
global @ou32@$bctr$qg , @ou32@$bctr$qui , @ou32@$bctr$qpc
global @ou32@$bctr$qs , @ou32@$bctr$qd , @ou32@$bctr$qus
global @ou32@$bctr$qr4ou32 , @ou32@$brplu$q4ou32
global @ou32@$brmin$q4ou32 , @ou32@$brmul$q4ou32
global @ou32@$brdiv$q4ou32 , @$blss$q4ou32t1
global @$bleq$q4ou32t1 , @$bgtr$q4ou32t1
global @$bgeq$q4ou32t1 , @ou32@$od$qv , @ou32@$oi$qv
global @ou32@$oui$qv , @ou32@$og$qv , @ou32@$binc$qv
global @ou32@$bdec$qv , @ou32@$binc$qi , @ou32@$bdec$qi
global @$beql$q4ou32t1 , @$bneq$q4ou32t1



section _TEXT public align=1 class=CODE use32


; ou32 operator+(ou32 a, ou32 b)
; 0ra, 4P_AddressResult, 8P_a, 12P_b
@$badd$q4ou32t1:
mov eax, [ esp + 4 ]
mov ecx, [ esp + 8 ]
mov edx, [ esp + 12 ]
cmp ecx, -1
je .0
cmp edx, -1
je .0
add ecx, edx
jc .0
mov dword[eax], ecx
ret
.0:
mov dword[eax], -1
ret


; ou32 operator-(ou32 a, ou32 b)
@$bsub$q4ou32t1:
mov eax, [ esp + 4 ]
mov ecx, [ esp + 8 ]
mov edx, [ esp + 12 ]
cmp ecx, -1
je .0
cmp edx, -1
je .0
sub ecx, edx
jl .0
mov dword[eax], ecx
ret
.0:
mov dword[eax], -1
ret


; ou32 operator*(ou32 a, ou32 b)
@$bmul$q4ou32t1:
mov eax, [ esp + 8 ]
mov ecx, [ esp + 12 ]
cmp eax, -1
je .0
cmp ecx, -1
je .0
mul ecx
cmp edx, 0
jne .0
mov ecx, eax
mov eax, [ esp + 4 ]
mov dword[eax], ecx
ret
.0:
mov eax, [ esp + 4 ]
mov dword[eax], -1
ret

; a, c, r si possono usare
; ou32 operator/(ou32 a, ou32 b)
; 0ra, 4P_AddResult, 8P_a, 12P_b
@$bdiv$q4ou32t1:
mov eax, [ esp + 8 ]
mov ecx, [ esp + 12 ]
cmp eax, -1
je .0
cmp ecx, -1
je .0
xor edx, edx
div ecx
mov ecx, eax
mov eax, [ esp + 4 ]
mov dword[eax], ecx
ret
.0:
mov eax, [ esp + 4 ]
mov dword[eax], -1
ret


; int operator==(ou32 a, ou32 b)
@$beql$q4ou32t1:
mov eax, [ esp + 4 ]
sub eax, [esp+8]
jz .0
mov eax, 0
ret
.0:
mov eax, 1
ret
ret

; int operator!=(ou32 a, ou32 b)
@$bneq$q4ou32t1:
mov eax, [ esp + 4 ]
sub eax, [esp+8]
jz .0
mov eax, 1
ret
.0:
mov eax, 0
ret
ret

; int operator<(ou32 a, ou32 b)
; 1-2=-1<0 <=> 1<2
@$blss$q4ou32t1:
mov eax, [ esp + 4 ]
sub eax, [esp+8]
jb .0
mov eax, 0
ret
.0:
mov eax, 1
ret


; int operator<=(ou32 a, ou32 b)
@$bleq$q4ou32t1:
mov eax, [ esp + 4 ]
sub eax, [esp+8]
jbe .0
mov eax, 0
ret
.0:
mov eax, 1
ret


; int operator>(ou32 a, ou32 b)
@$bgtr$q4ou32t1:
mov eax, [ esp + 4 ]
sub eax, [esp+8]
ja .0
mov eax, 0
ret
.0:
mov eax, 1
ret



; int operator>=(ou32 a, ou32 b)
@$bgeq$q4ou32t1:
mov eax, [ esp + 4 ]
sub eax, [esp+8]
jae .0
mov eax, 0
ret
.0:
mov eax, 1
ret


; ou32::ou32(long double a)
@ou32@$bctr$qg:
sub esp, 8
mov ecx, [ esp + 12 ] ; a>0xFFFFFFF
FLD tword[esp+16] ; st=a
FCOM qword[offffffff]
FSTSW ax
sahf
jbe .0
FSTP qword[esp]
mov dword[ecx], 0xFFFFFFFF
jmp short .1
.0:
FISTP qword[esp]
mov edx, [esp]
mov [ecx], edx
.1:
mov eax, ecx
add esp, 8
ret

; ou32::ou32(double a)
; 0_1, 4_2, 8ra, 12P_this, 16P_a
@ou32@$bctr$qd:
sub esp, 8
mov ecx, [ esp + 12 ] ; a>0xFFFFFFF
FLD qword[esp+16] ; st=a
FCOM qword[offffffff]
FSTSW ax
sahf
jbe .0
FSTP qword[esp]
mov dword[ecx], 0xFFFFFFFF
jmp short .1
.0:
FISTP qword[esp]
mov edx, [esp]
mov [ecx], edx
.1:
mov eax, ecx
add esp, 8
ret

; ou32::ou32(char* a)
; ou32::ou32(unsigned a)
; 0ra, 4P_This, 8P_a
@ou32@$bctr$qpc:
@ou32@$bctr$qui:
mov eax, [ esp + 4 ]
mov ecx, [ esp + 8 ]
mov [eax], ecx
ret

; ou32::ou32(int a)
@ou32@$bctr$qi:
mov eax, [ esp + 4 ]
mov ecx, [ esp + 8 ]
cmp ecx, 0
jge .0
mov dword[eax], -1
ret
.0:
mov [eax], ecx
ret

; i can use eax, ecx, edx for the abi call
; ou32::ou32(short a)
; 0ra, 4P_This, 8P_a
@ou32@$bctr$qs:
mov eax, [ esp + 4 ]
mov ecx, [ esp + 8 ]
cmp cx, 0
jge .0
mov dword[eax], -1
ret
.0:
and ecx, 0xFFFF
mov [eax], ecx
ret

; ou32::ou32(unsigned short a)
@ou32@$bctr$qus:
mov eax, [ esp + 4 ]
mov ecx, [ esp + 8 ]
and ecx, 0xFFFF
mov [eax], ecx
ret

; ou32::ou32()
@ou32@$bctr$qv:
mov eax, [ esp + 4 ]
mov dword[eax], 0
ret


; ou32::ou32(ou32& a)
; NB: not in use
; 0ra, 4P_This, 8P_a
@ou32@$bctr$qr4ou32:
mov eax, [ esp + 4 ]
mov ecx, [ esp + 8 ]
cmp eax, ecx
je .0
mov edx, [ecx]
mov [eax], edx
.0:
ret

; ou32 ou32::operator+=(ou32 a)
; 0ra, 4P_this, 8P_a
@ou32@$brplu$q4ou32:
mov eax, [ esp + 4 ]
mov ecx, [ esp + 8 ]
mov edx, [eax]
cmp ecx, -1
je .0
cmp edx, -1
je .0
add ecx, edx
jc .0
mov dword[eax], ecx
ret
.0:
mov dword[eax], -1
ret


; ou32 ou32::operator-=(ou32 a)
@ou32@$brmin$q4ou32:
mov eax, [ esp + 4 ]
mov ecx, [ esp + 8 ]
mov edx, [eax]
cmp ecx, -1
je .0
cmp edx, -1
je .0
sub ecx, edx
jl .0
mov dword[eax], ecx
ret
.0:
mov dword[eax], -1
ret



; ou32 ou32::operator*=(ou32 a)
@ou32@$brmul$q4ou32:
mov edx, [ esp + 4 ]
mov eax, [ esp + 8 ]
mov ecx, [edx]
cmp eax, -1
je .0
cmp ecx, -1
je .0
mul ecx
cmp edx, 0
jne .0
mov ecx, eax
mov eax, [ esp + 4 ]
mov dword[eax], ecx
ret
.0:
mov eax, [ esp + 4 ]
mov dword[eax], -1
ret


; ou32 ou32::operator/=(ou32 a)
@ou32@$brdiv$q4ou32:
mov edx, [ esp + 4 ]
mov eax, [ esp + 8 ]
mov ecx, [edx]
cmp eax, -1
je .0
cmp ecx, -1
je .0
xor edx, edx
div ecx
mov ecx, eax
mov eax, [ esp + 4 ]
mov dword[eax], ecx
ret
.0:
mov eax, [ esp + 4 ]
mov dword[eax], -1
ret


; ou32::operator double()
; ou32::operator long double()
; 0F[0], 4F[1], 8ra, 12this
@ou32@$od$qv:
@ou32@$og$qv:
sub esp, 8
mov eax, [ esp + 12 ]
mov ecx, [eax]
mov dword[esp], ecx
mov dword[esp+4], 0
fild qword[esp]
add esp, 8
ret

; ou32::operator int()
; ou32::operator unsigned()
; 0ra, 4this
@ou32@$oi$qv:
@ou32@$oui$qv:
mov ecx, [ esp + 4 ]
mov eax, [ecx]
ret



; ou32 ou32::operator++()
; 0ra, 4P_AddressResult, 8P_this
@ou32@$binc$qv:
mov eax, [ esp + 4 ]
mov ecx, [ esp + 8 ]
mov edx, [ecx]
cmp edx, -1
je .0
inc edx
mov [eax], edx
mov [ecx], edx
ret
.0:
mov dword[eax], -1
ret


; ou32 ou32::operator--()
@ou32@$bdec$qv:
mov eax, [ esp + 4 ]
mov ecx, [ esp + 8 ]
mov edx, [ecx]
cmp edx, -1
je .0
dec edx
mov [eax], edx
mov [ecx], edx
ret
.0:
mov dword[eax], -1
ret


; ou32 ou32::operator++(int)
@ou32@$binc$qi:
mov eax, [ esp + 4 ]
mov ecx, [ esp + 8 ]
mov edx, [ecx]
cmp edx, -1
je .0
mov [eax], edx
inc edx
mov [ecx], edx
ret
.0:
mov dword[eax], -1
ret


; ou32 ou32::operator--(int)
@ou32@$bdec$qi:
mov eax, [ esp + 4 ]
mov ecx, [ esp + 8 ]
mov edx, [ecx]
cmp edx, -1
je .0
mov [eax], edx
dec edx
mov [ecx], edx
ret
.0:
mov dword[eax], -1
ret


; end nasm file

/* Begin Borland C++ file of name borlfile.cpp */
/* bcc32 borlfile.cpp nasmfile.obj */
/* "bcc32" is the Borland compiler */

#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>

class ou32
{public:
ou32(); /* convertitori */
ou32(unsigned a);
ou32(int a);
ou32(double a);
ou32(long double a);
ou32(char* a);
ou32(short a);
ou32(unsigned short a);
// ou32(ou32& a);
// ################
friend ou32 operator+(ou32 a, ou32 b);
friend ou32 operator-(ou32 a, ou32 b);
friend ou32 operator*(ou32 a, ou32 b);
friend ou32 operator/(ou32 a, ou32 b);

friend int operator<(ou32 a, ou32 b);
friend int operator<=(ou32 a, ou32 b);
friend int operator>(ou32 a, ou32 b);
friend int operator>=(ou32 a, ou32 b);

friend int operator==(ou32 a, ou32 b);
friend int operator!=(ou32 a, ou32 b);


friend istream& operator>>(istream& istr, ou32& a)
{return istr >> a.v;}
friend ostream& operator<<(ostream& ostr, ou32 a)
{return ostr << a.v;}

// ################
ou32 operator+=(ou32 a);
ou32 operator-=(ou32 a);
ou32 operator*=(ou32 a);
ou32 operator/=(ou32 a);
ou32 operator++();
ou32 operator++(int);
ou32 operator--();
ou32 operator--(int);

// ################
operator double();
operator int();
operator unsigned();
operator long double();
// ################
unsigned v;
};

char* mallocI(size_t v){return (char*) v;}

char* mallocII(ou32 a)
{if(a==(ou32) -1) return 0;
else return mallocI(a.v);
}

int main(void)
{long double oo;
double m;
unsigned u0, u1, r0;
ou32 a=9.0, b=21.0, c, r;
c=a+b;
printf("Il valore di c==%u\n", c);
oo=c; m=c;
printf("Il val.longdouble==%Lf"
" val.double= %f\n", oo, m);
c=-1;
printf("Valore iniziale == %x\n", c);
++c;
printf("Il valore di c==%x\n", c.v);
--c;
printf("Il valore di c==%x\n", c.v);

// you can try to overflow data here
l1:;
printf("Per uscire a==0, b==0, c==0\n");
printf("Inserisci il valore a> ");
if( scanf("%u", &a)!=1 ) return 0;
printf("Preso %u \n", a);
printf("Inserisci il valore b> ");
if( scanf("%u", &b)!=1 ) return 0;
printf("%c ", a<b? '+': (a==b? '=': '-'));
printf("Preso %u \n", b);
printf("Inserisci il valore c> ");
if( scanf("%u", &c)!=1 ) return 0;
printf("Preso %u \n", c);

r=a*b+c; r0=a.v*b.v+c.v;
printf("Risultato a*b+c=%u\n", r);
u0=(unsigned) mallocI(r0);
u1=(unsigned) mallocII(r);
printf("You can see how mallocI return a vector of %u bytes\n", u0);
printf("While mallocII return a vector of %u bytes \n", u1);
printf("The words \"0 bytes\" means that malloc return null\n");
if(r0!=0) goto l1;
return 0;
}

/*
note how beautifull are these numbers...
Inserisci il valore a> 429497
Preso 429497
Inserisci il valore b> 10000
Preso 10000
Inserisci il valore c> 90
Preso 90
Risultato a*b+c=4294967295
You can see how mallocI return a vector of 2794 bytes
While mallocII return a vector of 0 bytes
The words "0 bytes" means that malloc return null
Per uscire a==0, b==0, c==0
*/

Malcolm McLean

unread,
Aug 9, 2007, 4:47:35 PM8/9/07
to

"Źa\/b" <al@f.g> wrote in message
news:tipmb3di7m8o044ki...@4ax.com...

> this would be an example for using nasm and a c++ compiler all
> together (for doing a 32 bits type that overflow if something goes
> wrong)
>
Nice idea, integers that kick if abused.
Implement in C++ and see if the C++ operator overloading feature is all it
is cracked up to be.

In C the idea is unusable, because you need an explicit call for every
operation, and the code just isn't human-readable any more. However you
could propose another 10 types or so to add to the 14 integer types we
already have.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

jacob navia

unread,
Aug 9, 2007, 6:08:29 PM8/9/07
to
Źa\/b wrote:
> this would be an example for using nasm and a c++ compiler all
> together (for doing a 32 bits type that overflow if something goes
> wrong)
>
> using assembly and c++ has some disadvantage (because compiler has to
> use all the same operation for doing something (that i should
> reproduce in assembly))
> then i not understand many function that compiler use in the code
> (that i not add)
>
> but all this has the vantage of reduce written text code
> and if you have to write something that use the structure of type
> "ou32" you have to write more than me
>
> then i would say that type "ou32" is better of your beloved size_t
> that all you use in malloc and all the routines that has to deal with
> arrays
>
> not because is more fast but because it has the controll on overflow
> that size_t can not to have
>
> can you please point out to some error do you see below?
> what do you think on it?
>
> thank you
> -----------------------------------
[assembly code snipped for brevity]

This approach could (maybe) work, but the problem is that (at least in
C, do not know about C++) overflow is well defined for unsigned integers
or in general unsigned quantities. The result of that operation should
"wrap around".

What is NOT defined, is overflow with signed integers. This distinction
is not apparent in the code you posted.

In my opinion, this should be implemented in the compiler. In the
lcc-win32 compiler a compile time option lets you test for overflow each
of the four operations with signed numbers. This has many advantages,
above all it is simpler to use than having a new integer class. Even if
lcc-win32 implements operator overloading as an extension, I think the
code would have too much of a slowdown if for each addition you would
call a function, even if that function is inlined...

Concerning the assembler code you posted, I do not understand why you
test for carry and NOT for overflow. In my implementation at least, I
test for OVERFLOW after each operation and not just for the carry...

jacob

Keith Thompson

unread,
Aug 9, 2007, 6:35:03 PM8/9/07
to
jacob navia <ja...@jacob.remcomp.fr> writes:
[...]

> In my opinion, this should be implemented in the compiler. In the
> lcc-win32 compiler a compile time option lets you test for overflow
> each of the four operations with signed numbers. This has many
> advantages,
> above all it is simpler to use than having a new integer class. Even if
> lcc-win32 implements operator overloading as an extension, I think the
> code would have too much of a slowdown if for each addition you would
> call a function, even if that function is inlined...

What's an "integer class"? Do you mean "integer type"? (I see this
is cross-posted to comp.lang.c and comp.lang.c++, almost always a bad
idea -- but the OP is a known troll.)

Since overflow checking is perfectly valid in standard C, I'll ask
something about lcc-win32's implementation of it. You said "the four
operations"; I assume that means "+", "-", "*", "/". Does it check
for overflow *only* on those for operations? What about unary "-"?
"++"? "--"? "<<"? Conversions?

I'd almost rather not have overflow checking at all than have it only
for a limited set of operations.

--
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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

jacob navia

unread,
Aug 9, 2007, 6:58:22 PM8/9/07
to
Keith Thompson wrote:
> jacob navia <ja...@jacob.remcomp.fr> writes:
> [...]
>> In my opinion, this should be implemented in the compiler. In the
>> lcc-win32 compiler a compile time option lets you test for overflow
>> each of the four operations with signed numbers. This has many
>> advantages,
>> above all it is simpler to use than having a new integer class. Even if
>> lcc-win32 implements operator overloading as an extension, I think the
>> code would have too much of a slowdown if for each addition you would
>> call a function, even if that function is inlined...
>
> What's an "integer class"? Do you mean "integer type"? (I see this
> is cross-posted to comp.lang.c and comp.lang.c++, almost always a bad
> idea -- but the OP is a known troll.)
>
> Since overflow checking is perfectly valid in standard C, I'll ask
> something about lcc-win32's implementation of it. You said "the four
> operations"; I assume that means "+", "-", "*", "/". Does it check
> for overflow *only* on those for operations? What about unary "-"?
> "++"? "--"? "<<"? Conversions?
>
> I'd almost rather not have overflow checking at all than have it only
> for a limited set of operations.
>

Well, ++ and -- are additions and subtractions as far as I remember...
:-)

No, I do not check for overflow with <<. It makes no sense actually.

Unary minus can generate overflow only with -INT_MIN, I believe, so
it is a borderline case. Is it really worth the effort?

But you have a point here. At least in the case of unary minus it
is a valid point.

jacob

Keith Thompson

unread,
Aug 9, 2007, 7:37:33 PM8/9/07
to
jacob navia <ja...@jacob.remcomp.fr> writes:
> Keith Thompson wrote:
[...]

>> Since overflow checking is perfectly valid in standard C, I'll ask
>> something about lcc-win32's implementation of it. You said "the four
>> operations"; I assume that means "+", "-", "*", "/". Does it check
>> for overflow *only* on those for operations? What about unary "-"?
>> "++"? "--"? "<<"? Conversions?
>> I'd almost rather not have overflow checking at all than have it only
>> for a limited set of operations.
>>
>
> Well, ++ and -- are additions and subtractions as far as I remember...
> :-)

Which doesn't answer the question. They're often implemented using
different machine instructions, and they may be handled separately
within the compiler. Users of lcc-win32 would probably be interested
in knowing whether it performs overflow checking on "++" and "--"
operators, and you haven't said whether it does or not.

> No, I do not check for overflow with <<. It makes no sense actually.

So if someone writes 'x << 3' rather than the equivalent 'x * 8'
because he thinks it's more efficient (or because he's compiling
legacy code written to cater to old compilers where it really is
significantly more efficient), then he's going to lose overflow
checking?

> Unary minus can generate overflow only with -INT_MIN, I believe, so
> it is a borderline case. Is it really worth the effort?

<SARCASM>
No, not at all. Don't trouble yourself about it. I'm sure that would
*never* happen.
</SARCASM>

Unary minus can overflow. Make up your mind, are you doing overflow
checking, or aren't you?

> But you have a point here. At least in the case of unary minus it
> is a valid point.

If I were going to implement overflow checking, I'd carefully go
through every operation defined by the language, determine whether it
can ever overflow, and generate checks accordingly. I'd also look
carefully at floating-point, which you haven't mentioned.

Of course, since the behavior on signed integer overflow is undefined,
a compiler that checks for overflow only when the left operand is even
and the right operand is prime could be conforming. It's just a QoI
issue.

Army1987

unread,
Aug 9, 2007, 8:08:00 PM8/9/07
to

More sense than with divisions, how on Earth could they overflow?
--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower

Keith Thompson

unread,
Aug 9, 2007, 8:49:48 PM8/9/07
to
Army1987 <army...@NOSPAM.it> writes:
> On Fri, 10 Aug 2007 00:58:22 +0200, jacob navia wrote:
[...]

>> No, I do not check for overflow with <<. It makes no sense actually.
> More sense than with divisions, how on Earth could they overflow?

INT_MIN / (-1)

FLT_MIN / 0.01

It's also unclear whether lcc-win32 checks for division by zero, or
for floating-point overflow.

It doesn't really matter from a C language point of view (or C++,
sorry for continuing the inappropriate crosspost, followups redirected
to comp.lang.c). I actually like the idea of (optional) overflow
checking in C; it's permitted by the standard for signed and
floating-point types, and it doesn't even require an extension. It
would be nice to have an example of a compiler that does this
properly, but it appears we'll have to look elsewhere.

柑\/b

unread,
Aug 10, 2007, 1:44:55 AM8/10/07
to

there are operation where "wrap around" is a big error
(note how size_t is used always in the C standard library)

>What is NOT defined, is overflow with signed integers. This distinction
>is not apparent in the code you posted.

the same i write for unsigned type can be rewrite for signed

>In my opinion, this should be implemented in the compiler. In the
>lcc-win32 compiler a compile time option lets you test for overflow each
>of the four operations with signed numbers. This has many advantages,
>above all it is simpler to use than having a new integer class. Even if
>lcc-win32 implements operator overloading as an extension, I think the
>code would have too much of a slowdown if for each addition you would
>call a function, even if that function is inlined...

yes

>Concerning the assembler code you posted, I do not understand why you
>test for carry and NOT for overflow. In my implementation at least, I
>test for OVERFLOW after each operation and not just for the carry...

i use carry for unsigned types because i can do all with "jc" for
unsigned types (and never found the need of use "jo" for unsigned
until now)

>jacob

jacob navia

unread,
Aug 10, 2007, 3:35:06 AM8/10/07
to
Keith Thompson wrote:
> Army1987 <army...@NOSPAM.it> writes:
>> On Fri, 10 Aug 2007 00:58:22 +0200, jacob navia wrote:
> [...]
>>> No, I do not check for overflow with <<. It makes no sense actually.
>> More sense than with divisions, how on Earth could they overflow?
>
> INT_MIN / (-1)
>
> FLT_MIN / 0.01
>
> It's also unclear whether lcc-win32 checks for division by zero, or
> for floating-point overflow.
>

No, since integer division by zero will trap, making finding
the error easy.

Floating point overflow is well defined by the language and
I did not interfere with that.

[snip polemic]

user923005

unread,
Aug 10, 2007, 3:46:12 AM8/10/07
to
On Aug 10, 12:35 am, jacob navia <ja...@jacob.remcomp.fr> wrote:
> Keith Thompson wrote:

> > Army1987 <army1...@NOSPAM.it> writes:
> >> On Fri, 10 Aug 2007 00:58:22 +0200, jacob navia wrote:
> > [...]
> >>> No, I do not check for overflow with <<. It makes no sense actually.
> >> More sense than with divisions, how on Earth could they overflow?
>
> > INT_MIN / (-1)
>
> > FLT_MIN / 0.01
>
> > It's also unclear whether lcc-win32 checks for division by zero, or
> > for floating-point overflow.
>
> No, since integer division by zero will trap, making finding
> the error easy.

Unless it happens once every ten thousand invocations of the program,
making it incrediby difficult to find.

> Floating point overflow is well defined by the language and
> I did not interfere with that.

[snip]

jacob navia

unread,
Aug 10, 2007, 3:55:08 AM8/10/07
to
user923005 wrote:
> On Aug 10, 12:35 am, jacob navia <ja...@jacob.remcomp.fr> wrote:
>> Keith Thompson wrote:
>>> Army1987 <army1...@NOSPAM.it> writes:
>>>> On Fri, 10 Aug 2007 00:58:22 +0200, jacob navia wrote:
>>> [...]
>>>>> No, I do not check for overflow with <<. It makes no sense actually.
>>>> More sense than with divisions, how on Earth could they overflow?
>>> INT_MIN / (-1)
>>> FLT_MIN / 0.01
>>> It's also unclear whether lcc-win32 checks for division by zero, or
>>> for floating-point overflow.
>> No, since integer division by zero will trap, making finding
>> the error easy.
>
> Unless it happens once every ten thousand invocations of the program,
> making it incrediby difficult to find.
>

Well, and my compiler tests would succeed once
every ten thousand. It is the same!

I do not see any advantage of sofwtare checking
when the hardware does it anyway.

Army1987

unread,
Aug 10, 2007, 5:52:22 AM8/10/07
to
On Thu, 09 Aug 2007 17:49:48 -0700, Keith Thompson wrote:

> Army1987 <army...@NOSPAM.it> writes:
>> On Fri, 10 Aug 2007 00:58:22 +0200, jacob navia wrote:
> [...]
>>> No, I do not check for overflow with <<. It makes no sense actually.
>> More sense than with divisions, how on Earth could they overflow?
>
> INT_MIN / (-1)

Right.

> FLT_MIN / 0.01
1. We're talking about integers.
2. It doesn't overflow, for two reasons. You were thinking about
DBL_MAX?

Richard Bos

unread,
Aug 10, 2007, 7:12:18 AM8/10/07
to
Keith Thompson <ks...@mib.org> wrote:

> jacob navia <ja...@jacob.remcomp.fr> writes:
> [...]
> > In my opinion, this should be implemented in the compiler. In the
> > lcc-win32 compiler a compile time option lets you test for overflow
> > each of the four operations with signed numbers. This has many
> > advantages,
> > above all it is simpler to use than having a new integer class. Even if
> > lcc-win32 implements operator overloading as an extension, I think the
> > code would have too much of a slowdown if for each addition you would
> > call a function, even if that function is inlined...
>
> What's an "integer class"? Do you mean "integer type"? (I see this
> is cross-posted to comp.lang.c and comp.lang.c++, almost always a bad
> idea -- but the OP is a known troll.)

He is. It is interesting to note who has taken his suggestion seriously.
It is depressing to see who is taking _their_ replies seriously.

Richard

jacob navia

unread,
Aug 10, 2007, 10:35:49 AM8/10/07
to
Richard Bos wrote:
> Keith Thompson <ks...@mib.org> wrote:
>
>> jacob navia <ja...@jacob.remcomp.fr> writes:
>> [...]
>>> In my opinion, this should be implemented in the compiler. In the
>>> lcc-win32 compiler a compile time option lets you test for overflow
>>> each of the four operations with signed numbers. This has many
>>> advantages,
>>> above all it is simpler to use than having a new integer class. Even if
>>> lcc-win32 implements operator overloading as an extension, I think the
>>> code would have too much of a slowdown if for each addition you would
>>> call a function, even if that function is inlined...
>> What's an "integer class"? Do you mean "integer type"? (I see this
>> is cross-posted to comp.lang.c and comp.lang.c++, almost always a bad
>> idea -- but the OP is a known troll.)
>
> He is.

At least he posts his work here, not like many others that limits
themselves to empty gestures.

There is a real need to catch overflow that has been completely
neglected by the language.


It is interesting to note who has taken his suggestion seriously.

Those that have worked with this problem, and proposed a working
solution, with a freely available implementation.

> It is depressing to see who is taking _their_ replies seriously.

YOU for instance. You participate in this thread :-)

But obviously you do not count!

Keith Thompson

unread,
Aug 10, 2007, 3:05:48 PM8/10/07
to
Army1987 <army...@NOSPAM.it> writes:
> On Thu, 09 Aug 2007 17:49:48 -0700, Keith Thompson wrote:
>> Army1987 <army...@NOSPAM.it> writes:
>>> On Fri, 10 Aug 2007 00:58:22 +0200, jacob navia wrote:
>> [...]
>>>> No, I do not check for overflow with <<. It makes no sense actually.
>>> More sense than with divisions, how on Earth could they overflow?
>>
>> INT_MIN / (-1)
> Right.
>
>> FLT_MIN / 0.01
> 1. We're talking about integers.

We were talking about overflow; I decided to talk about floating-point
overflow as well as integer overflow.

> 2. It doesn't overflow, for two reasons. You were thinking about
> DBL_MAX?

You're right, DBL_MAX is a better example.

Two reasons?

Alan Curry

unread,
Aug 10, 2007, 3:53:52 PM8/10/07
to
In article <ln7io3u...@nuthaus.mib.org>,

Keith Thompson <ks...@mib.org> wrote:
>Army1987 <army...@NOSPAM.it> writes:
>> On Thu, 09 Aug 2007 17:49:48 -0700, Keith Thompson wrote:
>>> FLT_MIN / 0.01

>> 2. It doesn't overflow, for two reasons. You were thinking about
>> DBL_MAX?
>
>You're right, DBL_MAX is a better example.
>
>Two reasons?

FLT_MIN/0.01 is within the range of a float - you made it bigger instead of
smaller.

and

FLT_MIN/100.0 (what you really meant) is pretty likely to be within the range
of a double which is the precision actually used for the operation.

And maybe a couple more reasons: the loss of accuracy in FLT_MIN/(float)100
(what you really really meant) is an underflow, not an overflow; and it might
not lose accuracy at all in a floating point system with denormals. But that
would probably require decimal floating point so I bet it wasn't one of the
original two reasons.

--
Alan Curry
pac...@world.std.com

Keith Thompson

unread,
Aug 10, 2007, 4:22:08 PM8/10/07
to
pac...@TheWorld.com (Alan Curry) writes:
> In article <ln7io3u...@nuthaus.mib.org>,
> Keith Thompson <ks...@mib.org> wrote:
>>Army1987 <army...@NOSPAM.it> writes:
>>> On Thu, 09 Aug 2007 17:49:48 -0700, Keith Thompson wrote:
>>>> FLT_MIN / 0.01
>
>>> 2. It doesn't overflow, for two reasons. You were thinking about
>>> DBL_MAX?
>>
>>You're right, DBL_MAX is a better example.
>>
>>Two reasons?
>
> FLT_MIN/0.01 is within the range of a float - you made it bigger instead of
> smaller.

Argh, my mistake. I was thinking that FLT_MIN is a large negative
number, typically -FLT_MAX; in fact, it's a tiny positive number.

> and
>
> FLT_MIN/100.0 (what you really meant) is pretty likely to be within the range
> of a double which is the precision actually used for the operation.
>
> And maybe a couple more reasons: the loss of accuracy in FLT_MIN/(float)100
> (what you really really meant) is an underflow, not an overflow; and it might
> not lose accuracy at all in a floating point system with denormals. But that
> would probably require decimal floating point so I bet it wasn't one of the
> original two reasons.

Yeah, I should have used double, specifically DBL_MAX.

jacob navia

unread,
Aug 10, 2007, 4:33:32 PM8/10/07
to
Floating point overflow
-----------------------

The standard defines clearly what happens with floating point overflow.
The set of floating point environment flags is handled by the fe.*
functions and described in the standard header fenv.h

The user can set/unset and query those flags after/呆efore each floating
point operation.

This is a major improvement over the outdated C89 situation. See the
section 7.6 of the standard.

It is a pity that the standard did NOT specify what happens with integer
overflow, even if indirectly acknowledges that the operation results
in undefined behavior.

This is why it is not correct to mix floating point and integer overflow.
One is well defined, the other is not.

jacob

Keith Thompson

unread,
Aug 10, 2007, 5:14:53 PM8/10/07
to
jacob navia <ja...@jacob.remcomp.fr> writes:
> Floating point overflow
> -----------------------
>
> The standard defines clearly what happens with floating point overflow.
> The set of floating point environment flags is handled by the fe.*
> functions and described in the standard header fenv.h

Isn't support for that optional? In other words, I think a conforming
implementation can do anything it likes on floating-point overflow, as
long as it doesn't claim IEC 60599 conformance.

But it's good that the standard provides a description of how FP
overflow is to be handled for implementations that choose to do so.

The standard explicitly states that conversion to a floating-point
type invokes undefined behavior if the value cannot be represented in
the target type. And C99 6.5p5 says:

If an _exceptional condition_ occurs during the evaluation of an
expression (that is, if the result is not mathematically defined
or not in the range of representable values for its type), the
behavior is undefined.

(This doesn't apply to unsigned types, since reduction modulo 2**N is
part of the operation, so formally speaking the overflow doesn't
happen in the first place.)

[...]


> It is a pity that the standard did NOT specify what happens with integer
> overflow, even if indirectly acknowledges that the operation results
> in undefined behavior.

Did you mean "directly" rather than "indirectly"?

> This is why it is not correct to mix floating point and integer overflow.
> One is well defined, the other is not.

There is a significant difference, in that the standard provides an
*optional* framework for dealing with floating-point overflow; an
implementer who wants to do something similar for signed integer
overflow pretty much has to define the interfaces.

It's possible I'm misreading the standard; if so, please point out
where I'm mistaken.

jacob navia

unread,
Aug 10, 2007, 5:31:30 PM8/10/07
to Keith Thompson
Keith Thompson wrote:
> jacob navia <ja...@jacob.remcomp.fr> writes:
>> Floating point overflow
>> -----------------------
>>
>> The standard defines clearly what happens with floating point overflow.
>> The set of floating point environment flags is handled by the fe.*
>> functions and described in the standard header fenv.h
>
> Isn't support for that optional? In other words, I think a conforming
> implementation can do anything it likes on floating-point overflow, as
> long as it doesn't claim IEC 60599 conformance.
>

Obviously there will be implementations of C where the machine has no
floating point unit. In those machines, maybe this thing can
be skipped.

> But it's good that the standard provides a description of how FP
> overflow is to be handled for implementations that choose to do so.
>
> The standard explicitly states that conversion to a floating-point
> type invokes undefined behavior if the value cannot be represented in
> the target type. And C99 6.5p5 says:
>
> If an _exceptional condition_ occurs during the evaluation of an
> expression (that is, if the result is not mathematically defined
> or not in the range of representable values for its type), the
> behavior is undefined.
>
> (This doesn't apply to unsigned types, since reduction modulo 2**N is
> part of the operation, so formally speaking the overflow doesn't
> happen in the first place.)
>
> [...]
>> It is a pity that the standard did NOT specify what happens with integer
>> overflow, even if indirectly acknowledges that the operation results
>> in undefined behavior.
>
> Did you mean "directly" rather than "indirectly"?
>


Well it is missing the specifications of WHAT HAPPENS in case of integer
overflow.

>> This is why it is not correct to mix floating point and integer overflow.
>> One is well defined, the other is not.
>
> There is a significant difference, in that the standard provides an
> *optional* framework for dealing with floating-point overflow; an
> implementer who wants to do something similar for signed integer
> overflow pretty much has to define the interfaces.
>
> It's possible I'm misreading the standard; if so, please point out
> where I'm mistaken.
>

Floating point is optional. I have seen many implementations of C
(and done several with the embedded versions of my compiler system)
where there wasn't any floating point at all!

But IF there is floating point, it must be implemented along the lines
of the standard.

Now, why they didn't do the same for the integer exceptions (division by
zero, overflow) it is a mystery.

In general C99 advanced the language in floating point with very good
specifications, (environment, complex numbers) but left essential stuff
like integer overflow unspecified.

Ben Pfaff

unread,
Aug 10, 2007, 5:47:31 PM8/10/07
to
jacob navia <ja...@jacob.remcomp.fr> writes:

> Floating point is optional. I have seen many implementations of C
> (and done several with the embedded versions of my compiler system)
> where there wasn't any floating point at all!

I don't think that floating point is optional at all. Where do
you get this notion?
--
Ben Pfaff
http://benpfaff.org

CBFalconer

unread,
Aug 10, 2007, 5:49:59 PM8/10/07
to
jacob navia wrote:
>
... snip ...

>
> Obviously there will be implementations of C where the machine
> has no floating point unit. In those machines, maybe this thing
> can be skipped.

Such implementations, if lacking suitable libraries, do not meet
the requirements of the standard. A 'unit' is not needed, but the
operations are.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

jacob navia

unread,
Aug 10, 2007, 6:00:26 PM8/10/07
to

From my work in machines without floating point!

Alarm systems, communications programs, many things run without
floating point, and in my compiler system for embedded targets
floating point can be made completely optional.

The compiler will issue an error with any floating point
operation. This saves a lot of run time RAM, and the
programmers are aware of the limitations of the CPU, so it is not
a problem for anyone.

jacob navia

unread,
Aug 10, 2007, 6:02:22 PM8/10/07
to
CBFalconer wrote:
> jacob navia wrote:
> ... snip ...
>> Obviously there will be implementations of C where the machine
>> has no floating point unit. In those machines, maybe this thing
>> can be skipped.
>
> Such implementations, if lacking suitable libraries, do not meet
> the requirements of the standard. A 'unit' is not needed, but the
> operations are.
>

Many embedded systems run in 40-50K, with integer units period.

Installing a full fledged floating point emulator would take precious
RAM from the program.

Maybe those systems are not "Standard".

So what?

That's life. Not everybody needs floating point!

Keith Thompson

unread,
Aug 10, 2007, 6:26:35 PM8/10/07
to
jacob navia <ja...@jacob.remcomp.fr> writes:
> Keith Thompson wrote:
>> jacob navia <ja...@jacob.remcomp.fr> writes:
>>> Floating point overflow
>>> -----------------------
>>>
>>> The standard defines clearly what happens with floating point overflow.
>>> The set of floating point environment flags is handled by the fe.*
>>> functions and described in the standard header fenv.h
>> Isn't support for that optional? In other words, I think a
>> conforming
>> implementation can do anything it likes on floating-point overflow, as
>> long as it doesn't claim IEC 60599 conformance.
>>
>
> Obviously there will be implementations of C where the machine has no
> floating point unit. In those machines, maybe this thing can
> be skipped.

On a machine with no floating point unit, a conforming C
implementation must emulate FP in software. Floating point support is
not optional, even for standalone implementations. An implementation
that doesn't support floating-point is no more conforming than one
that doesn't support structs or arrays.

>> But it's good that the standard provides a description of how FP
>> overflow is to be handled for implementations that choose to do so.
>> The standard explicitly states that conversion to a floating-point
>> type invokes undefined behavior if the value cannot be represented in
>> the target type. And C99 6.5p5 says:
>> If an _exceptional condition_ occurs during the evaluation of an
>> expression (that is, if the result is not mathematically defined
>> or not in the range of representable values for its type), the
>> behavior is undefined.
>> (This doesn't apply to unsigned types, since reduction modulo 2**N is
>> part of the operation, so formally speaking the overflow doesn't
>> happen in the first place.)
>> [...]
>>> It is a pity that the standard did NOT specify what happens with integer
>>> overflow, even if indirectly acknowledges that the operation results
>>> in undefined behavior.
>> Did you mean "directly" rather than "indirectly"?
>
> Well it is missing the specifications of WHAT HAPPENS in case of integer
> overflow.

My point is that the standard *explicitly* says that the behavior is
undefined for integer overflow. See C99 6.5p5, which I quoted above.
It's not a major point; if the behavior were merely undefined by
omission, it would mean exactly the same thing.

>>> This is why it is not correct to mix floating point and integer overflow.
>>> One is well defined, the other is not.
>> There is a significant difference, in that the standard provides an
>> *optional* framework for dealing with floating-point overflow; an
>> implementer who wants to do something similar for signed integer
>> overflow pretty much has to define the interfaces.
>> It's possible I'm misreading the standard; if so, please point out
>> where I'm mistaken.
>>
>
> Floating point is optional. I have seen many implementations of C
> (and done several with the embedded versions of my compiler system)
> where there wasn't any floating point at all!

Such implementations are non-conforming. That's not necessarily a bad
thing; they might be quite useful. (Similarly, I've heard of
not-quite-C implementations where int is 8 bits.)

> But IF there is floating point, it must be implemented along the lines
> of the standard.

Yes, but some of the floating-point stuff in the standard is
mandatory, and some of it is optional. In particular, a conforming
implementation *must* support float, double, and long double, but it
*needn't* support Annex F:

An implementation that defines __STDC_IEC_559__ shall conform to
the specifications in this annex.

> Now, why they didn't do the same for the integer exceptions (division by
> zero, overflow) it is a mystery.
>
> In general C99 advanced the language in floating point with very good
> specifications, (environment, complex numbers) but left essential stuff
> like integer overflow unspecified.

Mandating some particular behavior for signed integer overflow would
have had a significant performance impact on many systems.

IMHO it wouldn't have been a bad idea to specify an *optional* set of
behavior for signed integer overflow, similar to what was done for
floating-point. But if the committee had tried to require overflow
checking unconditionally (banning, for example, the common wraparound
behavior on 2's-complement systems), the standard would have had even
greater acceptance problems that it's actually had.

If you want to argue that the standard should mandate signed integer
overflow checking anyway, feel free to do so in comp.std.c.

Keith Thompson

unread,
Aug 10, 2007, 6:30:45 PM8/10/07
to

Exactly, they are non-conforming.

> So what?

So this is comp.lang.c.

> That's life. Not everybody needs floating point!

I don't think anyone here has claimed otherwise. We're merely
stating the rather obvious fact that floating-point support
is unconditionally required by the C standard. Non-conforming
implementations may be quite useful, but this is comp.lang.c, not
comp.lang.almost-but-not-quite-c.

Flash Gordon

unread,
Aug 10, 2007, 6:20:29 PM8/10/07
to
jacob navia wrote, On 10/08/07 23:00:

> Ben Pfaff wrote:
>> jacob navia <ja...@jacob.remcomp.fr> writes:
>>
>>> Floating point is optional. I have seen many implementations of C
>>> (and done several with the embedded versions of my compiler system)
>>> where there wasn't any floating point at all!
>>
>> I don't think that floating point is optional at all. Where do
>> you get this notion?
>
> From my work in machines without floating point!

I've worked on processors without FPUs but the C implementations still
supported floating point since it is and always has been part of C.

> Alarm systems, communications programs, many things run without
> floating point,

Yes, it's quite easy to do this, you just don't use any floating point
in your code.

> and in my compiler system for embedded targets
> floating point can be made completely optional.
>
> The compiler will issue an error with any floating point
> operation.

Well, with floating point disabled it is not a C compiler, just a
compiler for a language similar to C.

> This saves a lot of run time RAM,

Strangely enough most compilers don't use RAM for types that are not used.

> and the
> programmers are aware of the limitations of the CPU, so it is not
> a problem for anyone.

Well, it means the implementation does not conform to any version of the
C standard or K&R.

Personally I find not using things I don't want to use to be sufficient
for the implementation not to waste resources on them. So I would always
choose a compiler that provided floating point over one that did not so
that *if* I later needed it I would have it. Floating point has been
provided on processors without FPUs for a few decades at least.
--
Flash Gordon

Flash Gordon

unread,
Aug 10, 2007, 6:12:20 PM8/10/07
to
jacob navia wrote, On 10/08/07 22:31:

> Keith Thompson wrote:
>> jacob navia <ja...@jacob.remcomp.fr> writes:
>>> Floating point overflow
>>> -----------------------
>>>
>>> The standard defines clearly what happens with floating point overflow.
>>> The set of floating point environment flags is handled by the fe.*
>>> functions and described in the standard header fenv.h
>>
>> Isn't support for that optional? In other words, I think a conforming
>> implementation can do anything it likes on floating-point overflow, as
>> long as it doesn't claim IEC 60599 conformance.
>
> Obviously there will be implementations of C where the machine has no
> floating point unit. In those machines, maybe this thing can
> be skipped.

Any implementation can skip IEC 60599. The C standard does not say it
can be skipped "if so and so is true" it just says it is optional. There
are several good reasons it might not be followed.

<snip>

>>> It is a pity that the standard did NOT specify what happens with integer
>>> overflow, even if indirectly acknowledges that the operation results
>>> in undefined behavior.
>>
>> Did you mean "directly" rather than "indirectly"?
>
> Well it is missing the specifications of WHAT HAPPENS in case of integer
> overflow.

It explicitly states that it is undefined, so that is direct not indirect.

>>> This is why it is not correct to mix floating point and integer
>>> overflow.
>>> One is well defined, the other is not.
>>
>> There is a significant difference, in that the standard provides an
>> *optional* framework for dealing with floating-point overflow; an
>> implementer who wants to do something similar for signed integer
>> overflow pretty much has to define the interfaces.
>>
>> It's possible I'm misreading the standard; if so, please point out
>> where I'm mistaken.
>
> Floating point is optional.

Not in C it isn't.

> I have seen many implementations of C
> (and done several with the embedded versions of my compiler system)
> where there wasn't any floating point at all!

Well, they were not C implementations according to any version of the C
standard or K&R1.

> But IF there is floating point, it must be implemented along the lines
> of the standard.

Wrong. Floating point is not optional but conformance to IEC 60599 is.

> Now, why they didn't do the same for the integer exceptions (division by
> zero, overflow) it is a mystery.

Not all processors handle it in the same way. They could have specified
an optional standard, but they did not.

> In general C99 advanced the language in floating point with very good
> specifications, (environment, complex numbers) but left essential stuff
> like integer overflow unspecified.

Obviously a lot of people, specifically a number of those on the
standards committees, did not consider it essential.
--
Flash Gordon

Ben Pfaff

unread,
Aug 10, 2007, 6:39:29 PM8/10/07
to
jacob navia <ja...@jacob.remcomp.fr> writes:

> Ben Pfaff wrote:
>> jacob navia <ja...@jacob.remcomp.fr> writes:
>>
>>> Floating point is optional. I have seen many implementations of C
>>> (and done several with the embedded versions of my compiler system)
>>> where there wasn't any floating point at all!
>>
>> I don't think that floating point is optional at all. Where do
>> you get this notion?
>
> From my work in machines without floating point!

A "C" implementation without floating point is non-conforming.
It's not optional from the viewpoint of the standard.

Dik T. Winter

unread,
Aug 10, 2007, 6:24:48 PM8/10/07
to
In article <46BCD932...@jacob.remcomp.fr> jacob navia <ja...@jacob.remcomp.fr> writes:
> Keith Thompson wrote:
> > jacob navia <ja...@jacob.remcomp.fr> writes:
> >> Floating point overflow
> >> -----------------------
> >>
> >> The standard defines clearly what happens with floating point overflow.
> >> The set of floating point environment flags is handled by the fe.*
> >> functions and described in the standard header fenv.h
> >
> > Isn't support for that optional? In other words, I think a conforming
> > implementation can do anything it likes on floating-point overflow, as
> > long as it doesn't claim IEC 60599 conformance.
>
> Obviously there will be implementations of C where the machine has no
> floating point unit. In those machines, maybe this thing can
> be skipped.

The exceptions can be skipped on any implementation that does not have
the flags as intended, not only on systems missing floating point. From
the draft standard 7.6 par 5:
Each of the macros FE_DIVBYZERO, FE_INEXACT, FE_INVALID, FE_OVERFLOW,
FE_UNDERFLOW is defined if and only if the implementation supports
the exception by means of the functions in 7.6.2.
And 7.6.2:
The following functions provide access to the exception flags.
... fegetexceptflag() ...
So the best thing you can do is something like:

#ifdef FE_OVERFLOW
fegetexceptflag(...)
#else
/* other means to check for overflow */
#endif

So if the system does not provide an overflow indicator, FE_OVERFLOW must
not be defined, and you have no indication whether overflow did occur or
not.

I do not think this has changed much in the final standard.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/

Malcolm McLean

unread,
Aug 11, 2007, 1:17:18 AM8/11/07
to

"Keith Thompson" <ks...@mib.org> wrote in message
news:lnabsz9...@nuthaus.mib.org...

> On a machine with no floating point unit, a conforming C
> implementation must emulate FP in software. Floating point support is
> not optional, even for standalone implementations. An implementation
> that doesn't support floating-point is no more conforming than one
> that doesn't support structs or arrays.
>
But such integer only implentations are not too uncommon. On a lot of
machines there is no real point having floating point. You can always buy my
book and see how to implement the routines yourself, should you need real
numbers on a little 8 bit embedded controller.

>
> Mandating some particular behavior for signed integer overflow would
> have had a significant performance impact on many systems.
>
Exactly. Whilst it is better to trap on integer overflow, unless there is
hardware support then the software will run at least half as slowly simply
to support this feature, because every arithmetical operation requires a
conditional. Nowadays that is often an acceptable tradeoff, but not in
low-level routines.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Malcolm McLean

unread,
Aug 11, 2007, 1:35:31 AM8/11/07
to

"Ben Pfaff" <b...@cs.stanford.edu> wrote in message
news:87wsw3v...@blp.benpfaff.org...
It is possible to write a non-trivial program without floating point. It is
not possible to write one without integers, except as an exercise.

柑\/b

unread,
Aug 11, 2007, 1:56:16 AM8/11/07
to
On Fri, 10 Aug 2007 11:12:18 GMT, (Richard Bos) wrote:
>He is. It is interesting to note who has taken his suggestion seriously.
>It is depressing to see who is taking _their_ replies seriously.

i make errors and this would be another one.
for example i'm making a mistake if the problem not exist,
if in real executables this problem (size_t overflow) not is found
or if it seen in a too few number of cases

>Richard

Army1987

unread,
Aug 11, 2007, 6:42:07 AM8/11/07
to
On Sat, 11 Aug 2007 06:35:31 +0100, Malcolm McLean wrote:

>
> "Ben Pfaff" <b...@cs.stanford.edu> wrote in message
> news:87wsw3v...@blp.benpfaff.org...
>> jacob navia <ja...@jacob.remcomp.fr> writes:
>>
>>> Floating point is optional. I have seen many implementations of C
>>> (and done several with the embedded versions of my compiler system)
>>> where there wasn't any floating point at all!
>>
>> I don't think that floating point is optional at all. Where do
>> you get this notion?
>>
> It is possible to write a non-trivial program without floating point. It is
> not possible to write one without integers, except as an exercise.

IIRC, on Commodore 64 Basic variables were floating-point unless
their name ended with '%' (for integers) or '$' (for strings), and
most programs didn't bother to use integer variables just because
they didn't need to store fractional numbers in them.

Flash Gordon

unread,
Aug 11, 2007, 6:21:08 AM8/11/07
to
Malcolm McLean wrote, On 11/08/07 06:35:

>
> "Ben Pfaff" <b...@cs.stanford.edu> wrote in message
> news:87wsw3v...@blp.benpfaff.org...
>> jacob navia <ja...@jacob.remcomp.fr> writes:
>>
>>> Floating point is optional. I have seen many implementations of C
>>> (and done several with the embedded versions of my compiler system)
>>> where there wasn't any floating point at all!
>>
>> I don't think that floating point is optional at all. Where do
>> you get this notion?
>>
> It is possible to write a non-trivial program without floating point. It
> is not possible to write one without integers, except as an exercise.

So? The language standard, and before that K&R, still specify floating
point as being part of the language, not an optional extra.
--
Flash Gordon

pete

unread,
Aug 11, 2007, 7:39:07 AM8/11/07
to
Flash Gordon wrote:
>
> Malcolm McLean wrote, On 11/08/07 06:35:
> >
> > "Ben Pfaff" <b...@cs.stanford.edu> wrote in message
> > news:87wsw3v...@blp.benpfaff.org...
> >> jacob navia <ja...@jacob.remcomp.fr> writes:
> >>
> >>> Floating point is optional. I have seen many implementations of C
> >>> (and done several with the embedded versions of my compiler
> >>> system)
> >>> where there wasn't any floating point at all!

I have done one too.

> >>
> >> I don't think that floating point is optional at all.

It isn't.



> So? The language standard, and before that K&R, still specify floating
> point as being part of the language, not an optional extra.

You can write a correct C program that doesn't use floating point.
You can use a nonconforming C implementation
to translate and execute it.

q14.3 of the clc FAQ acknowledges that some implementations
of C, only link the math library as an option, not by default.

--
pete

Malcolm McLean

unread,
Aug 11, 2007, 7:40:37 AM8/11/07
to

"Army1987" <army...@NOSPAM.it> wrote in message
news:pan.2007.08.11....@NOSPAM.it...
And my own language, MiniBasic has only two basic data types, strings and
numbers. A number can be used as an array index. But most numbers will in
fact be integers.
However C programs is implied on comp.lang.c

Kenny McCormack

unread,
Aug 11, 2007, 4:17:27 PM8/11/07
to
In article <ln643n9...@nuthaus.mib.org>,
Keith Thompson <ks...@mib.org> wrote:
...

>I don't think anyone here has claimed otherwise. We're merely
>stating the rather obvious fact that floating-point support
>is unconditionally required by the C standard.

Stating the obvious is the stock in trade of the regs here.
Next up: Water is wet.

>Non-conforming
>implementations may be quite useful, but this is comp.lang.c, not
>comp.lang.almost-but-not-quite-c.

The problem is that y'all are acting as if Jacob has committed a crime
by including an option in his compiler system that, when specified (and
only then!), turns off FP in the generated code. Or, in your stilted
terminology, compiles a C-like language.

Get a life, guys. He ain't breaking any laws.

Flash Gordon

unread,
Aug 11, 2007, 5:00:39 PM8/11/07
to
pete wrote, On 11/08/07 12:39:

> Flash Gordon wrote:
>> Malcolm McLean wrote, On 11/08/07 06:35:
>>> "Ben Pfaff" <b...@cs.stanford.edu> wrote in message
>>> news:87wsw3v...@blp.benpfaff.org...
>>>> jacob navia <ja...@jacob.remcomp.fr> writes:
>>>>
>>>>> Floating point is optional. I have seen many implementations of C
>>>>> (and done several with the embedded versions of my compiler
>>>>> system)
>>>>> where there wasn't any floating point at all!
>
> I have done one too.
>
>>>> I don't think that floating point is optional at all.
>
> It isn't.
>
>> So? The language standard, and before that K&R, still specify floating
>> point as being part of the language, not an optional extra.
>
> You can write a correct C program that doesn't use floating point.

True.

> You can use a nonconforming C implementation
> to translate and execute it.

True.

> q14.3 of the clc FAQ acknowledges that some implementations
> of C, only link the math library as an option, not by default.

Yes, and without that option specified they are not conforming. It is
normal to have to specify options to make an implementation conform.

Personally, if I was writing a compiler for a processor without and FPU
I would implement floating point in SW, which is what the compilers for
the TMS320C1x/2x/5x do. If this is done properly, possibly with an
"optimising" linker that only includes code that is actually called,
then there is no overhead for programs not using floating point and it
is available if you actually require it.

There is a very long history of implementing floating point in SW since
until the 80486DX the 80x86 series of processors did not have a build in
FPU (although one was available as a co-processor it was not fitten in
all PCs) and it was only with the Pentium that Intel stopped doing
versions without an FPU (the 80486SX did not have an FPU built in).
--
Flash Gordon

Alexei A. Frounze

unread,
Aug 12, 2007, 6:22:04 AM8/12/07
to

Btw, 20.6b to which refers 14.3 is wrong:
-----8<-----
For example, here is a ``careful'' addition function:
int
chkadd(int a, int b)
{
if(INT_MAX - b < a) {
fputs("int overflow\n", stderr);
return INT_MAX;
}
return a + b;
}
-----8<-----
How about b = -1, a = INT_MIN being inputs of this "carefully" adding
function?
The above looks like the implementation for unsigned addends that was
turned into signed addition w/o much or any thinking by simply
changing unsigned int's to int's and UINT_MAX to INT_MAX. The correct
implementation would be:

if (b >= 0)
{
if (INT_MAX - b < a)) {
fputs("int overflow\n", stderr);
return INT_MAX;
}
}
else
{
if (INT_MIN - b > a)) {
fputs("int overflow\n", stderr);
return INT_MIN;
}
}
return a + b;

Alex

柑\/b

unread,
Aug 13, 2007, 2:25:30 AM8/13/07
to
On Thu, 9 Aug 2007 21:47:35 +0100, "Malcolm McLean" wrote:
>"Źa\/b" <al@f.g> wrote in message
>news:tipmb3di7m8o044ki...@4ax.com...
>> this would be an example for using nasm and a c++ compiler all
>> together (for doing a 32 bits type that overflow if something goes
>> wrong)
>>
>Nice idea, integers that kick if abused.
>Implement in C++ and see if the C++ operator overloading feature is all it
>is cracked up to be.
>
>In C the idea is unusable, because you need an explicit call for every
>operation,

it seems yes; i need to define a function for each type or explicity
say what function to call using cast

>and the code just isn't human-readable any more. However you
>could propose another 10 types or so to add to the 14 integer types we
>already have.

0 new messages