473,395 Members | 1,532 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

size_t or int for malloc-type functions?

Rcently I posted code in this group, to help a user
that asked to know how he could find out the size of
a block allocated with malloc.

As always when I post something, the same group
of people started to try to find possible errors,
a harmless passtime they seem to enjoy.

One of their remarks was that I used "int" instead of
"size_t" for the input of my allocator function.

As I explained, I prefer a signed type to the
unsigned size_t because small negative number will be
confused with huge integers when interpreted as unsigned.

I researched a bit the subject, and I found a type

ssize_t

The name is defined for instance in
http://www.delorie.com/gnu/docs/glibc/libc_239.html

Data Type: ssize_t
This data type is used to represent the sizes of blocks that can be
read or written in a single operation. It is similar to size_t, but must
be a signed type.

Another reference to this type appears in:
http://bochs.sourceforge.net/cgi-bin...dent?i=ssize_t
with
#define ssize_t long

This concern with the usage of an unsigned type that can be
easily lead to errors (of course only for people that do
make errors like me...) is also expressed in the document
ISO/IEC JTC1 SC22 WG14 N1135 :
"Specification for Safer, More Secure C Library Functions"
where they propose:

Extremely large object sizes are frequently a sign that an object’s size
was calculated incorrectly. For example, negative numbers appear as very
large positive numbers when converted to an unsigned type like size_t.

Also, some implementations do not support objects as large as the
maximum value that can be represented by type size_t.

For those reasons, it is sometimes beneficial to restrict the range of
object sizes to detect programming errors.

They propose having an unsigned rsize_t, but a macro RSIZE_MAX that
would limit the range of the object size.

I post this to document why having an "int" as an argument to a
malloc-type function is not such a bad idea.

Your opinion may differ.

jacob
Dec 31 '06
318 12665
On Tue, 02 Jan 2007 16:55:55 +0100, in comp.lang.c , jacob navia
<ja***@jacob.remcomp.frwrote:
>
65521 x 65552 is 65296 and NOT 4295032592
<sarcasm>
Apparently an entire realm of mathematics has been lost to the world.

Luckily I kept a papyrus scroll describing modular maths in my
pyramid, against just such an eventuality. We'd better hope the
barbarians don't try to set fire to it.
</sarcasm>

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Jan 2 '07 #101
Ben Pfaff a écrit :
"Old Wolf" <ol*****@inspire.net.nzwrites:

>>Richard Heathfield wrote:
>>>No, you don't get overflow with unsigned types.

Actually you do. However, the behaviour on overflow is well-defined.


C99 6.2.5p9 makes it pretty clear that the Standard takes Richard's
point of view:

A computation involving unsigned operands can never
overflow, [...]
wrong

If you quote the full text it says:

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

When the result "cannot be represented by the resulting
integer type" ... If this is not overflow I do not know
what overflow actually means!!!!

This famous paragraph just says that when the computation overflows
it will be reduced modulo "the number that is one greater than
the largest value". I.e. the behavior all CPUs had since ages when
a multiplication overflows!!!

This is just playing with words for NO REASON!!!

Jan 3 '07 #102
On 2 Jan 2007 15:05:33 -0800, in comp.lang.c , "Old Wolf"
<ol*****@inspire.net.nzwrote:
>Mark McIntyre wrote:
>If the argument is unsigned, you can't pass a -ve value to it.

"argument" means the value passed in. In this code:

#include <stdlib.h>
int foo() { malloc(-1); }

the argument to malloc is the value -1 (of type int).
No, thats just how you typed it. As far as malloc is concerned, you
passed UINT_MAX.

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Jan 3 '07 #103
jacob navia <ja***@jacob.remcomp.frwrites:
[...]
lcc-win32 uses this:

void *calloc(size_t n,size_t s)
{
long long siz = (long long)n * (long long)s;
void *result;
if (siz>>32)
return 0;
result = malloc((size_t)siz);
if (result)
memset(result,0,(size_t)siz);
return result;
}
Which of course is non-portable; there's no guarantee that long long
is bigger than size_t, or that size_t is 32 bits. (That's not a
criticism; code in a C library implementation is not required to be
portable.)

Incidentally, the casts in the arguments to malloc() and memset()
aren't necessary; the value of siz will be converted implicitly to
size_t as long as the declarations of malloc() and memset() are
visible. That's a style issue; the generated code should be the same
with or without the casts.

I wonder if "siz&~0xFFFFFFFF" might be marginally more efficient than
"siz>>32". It tests the upper 32 bits of siz without having to shift
them into the lower 32 bits. I have no particular expectation that it
*is* more efficient, and it's the kind of micro-optimization I
wouldn't recommend in ordinary code, but it might be appropriate in a
runtime library. (I expect it would be faster on some systems, slower
on others, and equivalent on yet others, but if you're only targeting
a single platform it's something to think about.)
sizeof(long long)=8*8
sizeof(size_t)=4*8
Quibble: I think you mean:

CHAR_BIT=8
sizeof(long long)=8
sizeof(size_t)=4

As you know, sizeof yields the size in bytes, not in bits.

--
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.
Jan 3 '07 #104
jacob navia <ja***@jacob.remcomp.frwrites:
Ben Pfaff a écrit :
>"Old Wolf" <ol*****@inspire.net.nzwrites:
>>>Richard Heathfield wrote:
No, you don't get overflow with unsigned types.
Actually you do. However, the behaviour on overflow is well-defined.


C99 6.2.5p9 makes it pretty clear that the Standard takes Richard's
point of view:

A computation involving unsigned operands can never
overflow, [...]

wrong

If you quote the full text it says:

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

When the result "cannot be represented by the resulting
integer type" ... If this is not overflow I do not know
what overflow actually means!!!!
Based on its use in the Standard, I'd guess that the meaning of
overflow in the committee's minds is an exceptional condition
that yields undefined behavior. Because out-of-range unsigned
values are not treated exceptionally and do not yield undefined
behavior, they are not examples of overflow under this
definition. Indeed, the Standard uses "integer overflow" as its
stock example of undefined behavior, not "signed integer
overflow", because "unsigned integer overflow" is a contradiction
in terms according to this definition.

Here is part of what the Rationale says about integer overflow.
I believe that it supports my position:

The keyword unsigned is something of a misnomer, suggesting
as it does in arithmetic that it is non-negative but
capable of overflow. The semantics of the C type unsigned
is that of modulus, or wrap-around, arithmetic for which
overflow has no meaning. The result of an unsigned
arithmetic operation is thus always defined, whereas the
result of a signed operation may be undefined.
--
"I'm not here to convince idiots not to be stupid.
They won't listen anyway."
--Dann Corbit
Jan 3 '07 #105
Keith Thompson <ks***@mib.orgwrites:
jacob navia <ja***@jacob.remcomp.frwrites:
>void *calloc(size_t n,size_t s)
{
long long siz = (long long)n * (long long)s;
void *result;
if (siz>>32)
return 0;
result = malloc((size_t)siz);
if (result)
memset(result,0,(size_t)siz);
return result;
}
[...]
I wonder if "siz&~0xFFFFFFFF" might be marginally more efficient than
"siz>>32". [...]
I'd recommend "siz SIZE_MAX" as being both clear and portable.
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Jan 3 '07 #106
Keith Thompson a écrit :
jacob navia <ja***@jacob.remcomp.frwrites:
[...]
>>lcc-win32 uses this:

void *calloc(size_t n,size_t s)
{
long long siz = (long long)n * (long long)s;
void *result;
if (siz>>32)
return 0;
result = malloc((size_t)siz);
if (result)
memset(result,0,(size_t)siz);
return result;
}


Which of course is non-portable; there's no guarantee that long long
is bigger than size_t, or that size_t is 32 bits. (That's not a
criticism; code in a C library implementation is not required to be
portable.)
This is portable to all systems where
1) long long is 64 bits
2) size_t is 32 bits
Incidentally, the casts in the arguments to malloc() and memset()
aren't necessary; the value of siz will be converted implicitly to
size_t as long as the declarations of malloc() and memset() are
visible.
True.

That's a style issue; the generated code should be the same
with or without the casts.

I wonder if "siz&~0xFFFFFFFF" might be marginally more efficient than
"siz>>32". It tests the upper 32 bits of siz without having to shift
them into the lower 32 bits. I have no particular expectation that it
*is* more efficient, and it's the kind of micro-optimization I
wouldn't recommend in ordinary code, but it might be appropriate in a
runtime library. (I expect it would be faster on some systems, slower
on others, and equivalent on yet others, but if you're only targeting
a single platform it's something to think about.)
In the 32 bit version of lcc-win32 (the other is called lcc-win64)
a long long is splitted anyway, a shift of 32 produces actually
no shifts in my implementation, I just access the upper 32 bits.
If its in memory I access the upper 32 bits, and if it is in
the register pair EAX:EDX I just access EDX.

I am used to this since I programmed this optimization, and
then I do not realize that other compilers would be maybe different.

>
>>sizeof(long long)=8*8
sizeof(size_t)=4*8


Quibble: I think you mean:

CHAR_BIT=8
sizeof(long long)=8
sizeof(size_t)=4

As you know, sizeof yields the size in bytes, not in bits.
Yes. Thanks
Jan 3 '07 #107
"Old Wolf" <ol*****@inspire.net.nzwrites:
Richard Heathfield wrote:
>>
No, you don't get overflow with unsigned types.

Actually you do. However, the behaviour on overflow is well-defined.

I suppose you could quibble about the exact meaning of the word
'overflow', but it is clear what Navia's meaning is and it serves no
purpose to pretend he is saying something other than what he is.
The standard's use of the term "overflow" is unambiguous. It
explicitly does *not* use that term to refer to an unsigned
calculation whose "mathematical result" cannot be represented in the
result type.

It easily *could* have use the term "overflow" to describe this (and I
think I would have been happier if it had), but it didn't. We're not
going to be able to communicate about this unless we have a common
vocabulary; I suggest that the only common vocabulary that we can use
is the one used by the standard.

Yes, I know what jacob means by "overflow", but communication would be
easier if he'd refrain from using that term in contradiction to the
way the standard uses it, especially in the context of the very
section of the standard that says quite clearly that unsigned
operations cannot overflow. It's like saying that a system with
CHAR_BIT==16 has 2-byte characters. Call it "wraparound", or
"reduction modulo 2**N", or at least put the word "overflow" in
quotation marks and make it clear that you're not using the term the
way the standard does.

--
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.
Jan 3 '07 #108
In article <11*********************@h40g2000cwb.googlegroups. com>,
Old Wolf <ol*****@inspire.net.nzwrote:
>Richard Heathfield wrote:
>>
No, you don't get overflow with unsigned types.

Actually you do. However, the behaviour on overflow is well-defined.

I suppose you could quibble about the exact meaning of the word
'overflow', but it is clear what Navia's meaning is and it serves no
purpose to pretend he is saying something other than what he is.
Obviously true - for anyone with an IQ above 15.

But pigs will fly and hell will freeze over before heathfield admits to
so much as understanding, much less agreeing with, anything posted by Navia.

As someone else pointed out, part of the ethos of clc is that to even
admit to understanding someone's post is to be seen as, to some extent,
agreeing with it. In order to keep up your macho reputation, you have
to totally misrepresent any post by anyone you don't like.

Jan 3 '07 #109
In article <11*********************@h40g2000cwb.googlegroups. com>,
Old Wolf <ol*****@inspire.net.nzwrote:
>Mark McIntyre wrote:
>If the argument is unsigned, you can't pass a -ve value to it.

"argument" means the value passed in. In this code:

#include <stdlib.h>
int foo() { malloc(-1); }

the argument to malloc is the value -1 (of type int).

The type "size_t" w.r.t. malloc is known as the "formal parameter type"
(often the word 'formal' is dropped for convenience's sake).
Obviously true. But the dim bulbs around here are never going to admit it.

Jan 3 '07 #110
On Wed, 03 Jan 2007 01:20:10 +0100, in comp.lang.c , jacob navia
<ja***@jacob.remcomp.frwrote:
>This is portable to all systems where
1) long long is 64 bits
2) size_t is 32 bits
Which limits it to a fairly small subset of systems, by the way...
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Jan 3 '07 #111
Ben Pfaff a écrit :
jacob navia <ja***@jacob.remcomp.frwrites:
>>When the result "cannot be represented by the resulting
integer type" ... If this is not overflow I do not know
what overflow actually means!!!!


Based on its use in the Standard, I'd guess that the meaning of
overflow in the committee's minds is an exceptional condition
that yields undefined behavior. Because out-of-range unsigned
values are not treated exceptionally and do not yield undefined
behavior, they are not examples of overflow under this
definition. Indeed, the Standard uses "integer overflow" as its
stock example of undefined behavior, not "signed integer
overflow", because "unsigned integer overflow" is a contradiction
in terms according to this definition.

Here is part of what the Rationale says about integer overflow.
I believe that it supports my position:

The keyword unsigned is something of a misnomer, suggesting
as it does in arithmetic that it is non-negative but
capable of overflow. The semantics of the C type unsigned
is that of modulus, or wrap-around, arithmetic for which
overflow has no meaning. The result of an unsigned
arithmetic operation is thus always defined, whereas the
result of a signed operation may be undefined.
Yes, I know that, and I agree that the semantics of unsigned is
wrap around. What I am saying is that when "the result cannot be
represented" and this wrap around semantics reduces the result,
this reduced result is mathematically WRONG in the sense of the USUAL
multiplication operation.

PHEW!!!!

Specifically when I use the malloc (p * sizeof *p) "idiom"
even if the semantics are well defined this is NOT what I
inteded with that multiplication!!!!

There is no point in throwing me standards texts because I am not
questioning them. I am just saying that this "results that cannot be
represented" lead to a wrong result being passed to malloc!!!
I just can't understand why it is impossible to agree in such
an evident stuff !!!
Jan 3 '07 #112
jacob navia <ja***@jacob.remcomp.frwrites:
Ben Pfaff a écrit :
>jacob navia <ja***@jacob.remcomp.frwrites:
>>>When the result "cannot be represented by the resulting
integer type" ... If this is not overflow I do not know
what overflow actually means!!!!

Based on its use in the Standard, I'd guess that the meaning of
overflow in the committee's minds is an exceptional condition
that yields undefined behavior. Because out-of-range unsigned
values are not treated exceptionally and do not yield undefined
behavior, they are not examples of overflow under this
definition. Indeed, the Standard uses "integer overflow" as its
stock example of undefined behavior, not "signed integer
overflow", because "unsigned integer overflow" is a contradiction
in terms according to this definition.

Here is part of what the Rationale says about integer overflow.
I believe that it supports my position:

The keyword unsigned is something of a misnomer, suggesting
as it does in arithmetic that it is non-negative but
capable of overflow. The semantics of the C type unsigned
is that of modulus, or wrap-around, arithmetic for which
overflow has no meaning. The result of an unsigned
arithmetic operation is thus always defined, whereas the
result of a signed operation may be undefined.

Yes, I know that, and I agree that the semantics of unsigned is
wrap around. What I am saying is that when "the result cannot be
represented" and this wrap around semantics reduces the result,
this reduced result is mathematically WRONG in the sense of the USUAL
multiplication operation.
The problem that we have here is one of definitions. The
Standard defines "overflow" one way; you are defining it another.
If you want to say that the customary mathematical result and the
modulo result are different, that's one thing, but calling it
overflow just confuses everyone who is familiar with the C
language.
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Jan 3 '07 #113
jacob navia <ja***@jacob.remcomp.frwrites:
Keith Thompson a écrit :
>jacob navia <ja***@jacob.remcomp.frwrites:
[...]
>>>lcc-win32 uses this:

void *calloc(size_t n,size_t s)
{
long long siz = (long long)n * (long long)s;
void *result;
if (siz>>32)
return 0;
result = malloc((size_t)siz);
if (result)
memset(result,0,(size_t)siz);
return result;
}
Which of course is non-portable; there's no guarantee that long long
is bigger than size_t, or that size_t is 32 bits. (That's not a
criticism; code in a C library implementation is not required to be
portable.)

This is portable to all systems where
1) long long is 64 bits
2) size_t is 32 bits
[...]

Yes, and only to such systems. That's what I meant by "non-portable".

--
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.
Jan 3 '07 #114
jacob navia wrote:
christian.bau a écrit :
>CBFalconer wrote:
>>What this has brought home to me is that calloc should be included
in the nmalloc package, so that the same maximum size criterion
will be applied. I.E:

void *ncalloc(size_t nmemb, size_t size) {
size_t sz;
void *p;

sz = nmemb * size;
if ((sz < nmemb) || (sz < size)) return NULL;
if (p = nmalloc(sz)) memset(p, 0, sz);
return p;
}


Just wanted to say: This will not catch many problems. For example on a
32 bit system, nmemb = 0x10001, size = 0x10001, sz = 0x20001.

lcc-win32 uses this:

void *calloc(size_t n,size_t s)
{
long long siz = (long long)n * (long long)s;
void *result;
if (siz>>32)
return 0;
result = malloc((size_t)siz);
if (result)
memset(result,0,(size_t)siz);
return result;
}
Why not:

void *calloc(size_t n, size_t s) {
void *result;
size_t sz;
if(SIZE_MAX/n<s) {
sz=n*s;
result=malloc(n*s);
if(result) {
memset(result,0,sz);
return result;
}
}
return NULL;
}

?
--
Ioan - Ciprian Tandau
tandau _at_ freeshell _dot_ org (hope it's not too late)
(... and that it still works...)
Jan 3 '07 #115
jacob navia wrote:
Nevertheless this behavior of unsigned C arithmetic is
sureley NEVER CORRECT and I have never seen a useful
program that relies on this behavior for something useful.
Plenty of CRC and checksum generating code find this behavior useful.
Can't believe you've never seen them since they're all over the place.

Jan 3 '07 #116
Nelu wrote:
jacob navia wrote:
>christian.bau a écrit :
>>CBFalconer wrote:

What this has brought home to me is that calloc should be included
in the nmalloc package, so that the same maximum size criterion
will be applied. I.E:

void *ncalloc(size_t nmemb, size_t size) {
size_t sz;
void *p;

sz = nmemb * size;
if ((sz < nmemb) || (sz < size)) return NULL;
if (p = nmalloc(sz)) memset(p, 0, sz);
return p;
}

Just wanted to say: This will not catch many problems. For example on a
32 bit system, nmemb = 0x10001, size = 0x10001, sz = 0x20001.
lcc-win32 uses this:

void *calloc(size_t n,size_t s)
{
long long siz = (long long)n * (long long)s;
void *result;
if (siz>>32)
return 0;
result = malloc((size_t)siz);
if (result)
memset(result,0,(size_t)siz);
return result;
}

Why not:

void *calloc(size_t n, size_t s) {
void *result;
size_t sz;
if(SIZE_MAX/n<s) {
Sorry, '>'.
--
Ioan - Ciprian Tandau
tandau _at_ freeshell _dot_ org (hope it's not too late)
(... and that it still works...)
Jan 3 '07 #117
sl*******@yahoo.com a écrit :
jacob navia wrote:
>>Nevertheless this behavior of unsigned C arithmetic is
sureley NEVER CORRECT and I have never seen a useful
program that relies on this behavior for something useful.


Plenty of CRC and checksum generating code find this behavior useful.
Can't believe you've never seen them since they're all over the place.
When doing multiplications?

This is a crc code for instance:
/*
================================================== ======================= */
#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >8);
#define DO2(buf) DO1(buf); DO1(buf);
#define DO4(buf) DO2(buf); DO2(buf);
#define DO8(buf) DO4(buf); DO4(buf);

/*
================================================== ======================= */
uLong ZEXPORT crc32(crc, buf, len)
uLong crc;
const Bytef *buf;
uInt len;
{
if (buf == Z_NULL) return 0L;
#ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty)
make_crc_table();
#endif
crc = crc ^ 0xffffffffL;
while (len >= 8)
{
DO8(buf);
len -= 8;
}
if (len) do {
DO1(buf);
} while (--len);
return crc ^ 0xffffffffL;
}

No multiplications as far as I see.
Jan 3 '07 #118
Ben Pfaff <bl*@cs.stanford.eduwrites:
Keith Thompson <ks***@mib.orgwrites:
>jacob navia <ja***@jacob.remcomp.frwrites:
>>void *calloc(size_t n,size_t s)
{
long long siz = (long long)n * (long long)s;
void *result;
if (siz>>32)
return 0;
result = malloc((size_t)siz);
if (result)
memset(result,0,(size_t)siz);
return result;
}

[...]
>I wonder if "siz&~0xFFFFFFFF" might be marginally more efficient than
"siz>>32". [...]

I'd recommend "siz SIZE_MAX" as being both clear and portable.
Excellent! I wish I'd thought of that myself. It's much clearer to
the reader, and likely to be clearer to the compiler (i.e., there's a
greater potential for optimization if there happens to be an efficient
code sequence that does the same thing).

--
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.
Jan 3 '07 #119
jacob navia <ja***@jacob.remcomp.frwrites:
[...]
Yes, I know that, and I agree that the semantics of unsigned is
wrap around. What I am saying is that when "the result cannot be
represented" and this wrap around semantics reduces the result,
this reduced result is mathematically WRONG in the sense of the USUAL
multiplication operation.

PHEW!!!!
No, it is not "WRONG", it is *different*. Multiplication of unsigned
values does not follow the mathematical semantics of multiplication
over the infinite set of integers. It's not supposed to. If you're
going to use unsigned types in C, you just have to be aware of this.

Multiplication and other operations over a finite set (e.g., modulo N)
are well-defined and commonly used in mathematics, though probably
less common than operations on the infinite set of integers. This
finite arithmetic corresponds closely to the behavior of unsigned
integers in C.
Specifically when I use the malloc (p * sizeof *p) "idiom"
even if the semantics are well defined this is NOT what I
inteded with that multiplication!!!!
As I've said elsewhere in this thread, I actually agree with this
(except that you probably didn't want to use "p" twice). You have to
be careful to avoid operands that will result in wraparound. The real
bug is that you're asking for way too much memory; the problem is
aggravated by the fact that, due to the wraparound semantics of
unsigned types, the bug can be difficult to detect.

I emphatically do not agree that this means that the
p = malloc(COUNT * sizeof *p);
idiom is too dangerous to use. But providing a wrapper (similar to
calloc() but without the initialization to zero) isn't a bad idea.
There is no point in throwing me standards texts because I am not
questioning them. I am just saying that this "results that cannot be
represented" lead to a wrong result being passed to malloc!!!
I just can't understand why it is impossible to agree in such
an evident stuff !!!
It's largely because you insist on using the word "overflow" in direct
contradiction to the way the standard uses that same word. If you'll
use terminology consistent with the standard, it just might turn out
that we're largely in agreement (about the problem if not about the
solution).

--
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.
Jan 3 '07 #120
ku****@wizard.net wrote:
Kenny McCormack wrote:
.... snip ...
>>
The truly scary thing is that after reading RH's drivel for
a while, you begin to realize, that like his mentor Dubya,
he *actually* believes the claptrap he's spewing! I mean,
seriously, like Dubya, he's not lying!

And *that*, my friends, is the true definition of scary.

It's not claptrap, unlike what Dubya is spewing, and I would
therefore certainly hope he's sufficiently intelligent and
mathematically well-educated to believe it. I'd recommend
reading up on the mathematical concept of rings before you
claim otherwise.
It's all in the sig.

--
+-------------------+ .:\:\:/:/:.
| PLEASE DO NOT F :.:\:\:/:/:.:
| FEED THE TROLLS | :=.' - - '.=:
| | '=(\ 9 9 /)='
| Thank you, | ( (_) )
| Management | /`-vvv-'\
+-------------------+ / \
| | @@@ / /|,,,,,|\ \
| | @@@ /_// /^\ \\_\
@x@@x@ | | |/ WW( ( ) )WW
\||||/ | | \| __\,,\ /,,/__
\||/ | | | jgs (______Y______)
/\/\/\/\/\/\/\/\//\/\\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
================================================== ============

fix (vb.): 1. to paper over, obscure, hide from public view; 2.
to work around, in a way that produces unintended consequences
that are worse than the original problem. Usage: "Windows ME
fixes many of the shortcomings of Windows 98 SE". - Hutchinson
Jan 3 '07 #121
jacob navia wrote:
>
.... snip ...
>
Or are you implying that

65521 x 65552 is 65296 and NOT 4295032592
Yes, if done with unsigned shorts, i.e. any unsigned 16 bit type.
That's what the standard prescribes. Have you ever bothered to
read the standard? Without doing so how can you dare to modify the
lcc compiler?

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Jan 3 '07 #122
ku****@wizard.net wrote:
jacob navia wrote:
.... snip ...
>>
Who cares about rings?

Rings are the mathematical construct that correspond to the way
in which the C standard defines arithmetic for unsigned types.
IIRC a ring defines a set of objects that are members of the ring,
and a set of operations on those objects, such that <m1 operation
m2yields a member of the ring. unsigned objects and the
operations +, -, and * meet this definiton. The operation / does
not. Exponentiation does. Many bits have been dropped in my
memory, however.

The point is that you can prove things about the behaviour of
rings, and then immediately apply those results to anything that
meets the definition. Something like subroutines.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Jan 3 '07 #123
Old Wolf said:

<snip>
That aside, wouldn't it be more sensible behaviour for malloc to
return NULL or take some other action when you try request an
object bigger than the system can provide, rather than returning
a smaller object than requested?
But malloc does *not* return (a pointer to space for) a smaller object than
requested.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jan 3 '07 #124
jacob navia said:

<snip>
>
Specifically when I use the malloc (p * sizeof *p) "idiom"
even if the semantics are well defined this is NOT what I
inteded with that multiplication!!!!
Then write what you did intend.
There is no point in throwing me standards texts because I am not
questioning them. I am just saying that this "results that cannot be
represented" lead to a wrong result being passed to malloc!!!
If your program passes the wrong result to malloc, that is a bug in your
program, not a bug in malloc or in unsigned arithmetic.
I just can't understand why it is impossible to agree in such
an evident stuff !!!
What is obvious to one person is far from obvious to another, which is why
it is necessary to have independent standards - and these can often seem
arbitrary in the choices they make, precisely because one man's obvious is
another man's obscure.

The C language is defined not by random opinions on clc but by an
international standard, which frequently makes arbitrary choices (and
frequently does *not*, much to some people's frustration). If you want to
discuss the language rationally with other people, you'll need to get used
to that.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jan 3 '07 #125
Old Wolf said:
Richard Heathfield wrote:
>>
No, you don't get overflow with unsigned types.

Actually you do.
No, actually you don't.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jan 3 '07 #126
Richard Heathfield wrote:
... The width of size_t is implementation-defined. ...
SIZE_MAX is implementation-defined in C99, but AFAIK, C90 doesn't
require any facet of size_t to be implementation-defined.

--
Peter

Jan 3 '07 #127
Mark McIntyre said:
On 2 Jan 2007 15:05:33 -0800, in comp.lang.c , "Old Wolf"
<ol*****@inspire.net.nzwrote:
>>Mark McIntyre wrote:
>>If the argument is unsigned, you can't pass a -ve value to it.

"argument" means the value passed in. In this code:

#include <stdlib.h>
int foo() { malloc(-1); }

the argument to malloc is the value -1 (of type int).

No, thats just how you typed it.
No, the argument to malloc is the expression -1, which is clearly of type
int, and is equally clearly negative!
As far as malloc is concerned, you passed UINT_MAX.
No, malloc has no clue what you passed, and UINT_MAX has nothing to do with
it except, perhaps, coincidentally. As far as malloc is concerned, it
*receives* a parameter with the value (size_t)-1, which is a (very)
positive value.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jan 3 '07 #128
Peter Nilsson said:
Richard Heathfield wrote:
>... The width of size_t is implementation-defined. ...

SIZE_MAX is implementation-defined in C99, but AFAIK, C90 doesn't
require any facet of size_t to be implementation-defined.
Sorry, I should have said "implementation-dependent".

That is, clearly it has to be some width or other, and yet the Standard does
not say which width (except that we know it must be at least 15 bits wide
in C90, 16 in C99). So it depends on the implementation. Indeed, it is
defined by the implementation! Nevertheless, strictly speaking it is not
"implementation-defined" within the meaning of the Act.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jan 3 '07 #129
CBFalconer said:
ku****@wizard.net wrote:
>jacob navia wrote:
... snip ...
>>>
Who cares about rings?

Rings are the mathematical construct that correspond to the way
in which the C standard defines arithmetic for unsigned types.

IIRC a ring defines a set of objects that are members of the ring,
and a set of operations on those objects, such that <m1 operation
m2yields a member of the ring. unsigned objects and the
operations +, -, and * meet this definiton. The operation / does
not. Exponentiation does.
Well, a ring is a set with two defined binary operations, + and *, usually
taken to mean addition and multiplication, that meet a set of primitive
axiomatic conditions which I won't go into here. The existence of
additional operations (such as division) doesn't stop it being a ring even
if they don't meet the condition that m1 op m2 yields a member of the ring.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jan 3 '07 #130
Richard Heathfield <rj*@see.sig.invalidwrites:
Old Wolf said:

<snip>
>That aside, wouldn't it be more sensible behaviour for malloc to
return NULL or take some other action when you try request an
object bigger than the system can provide, rather than returning
a smaller object than requested?

But malloc does *not* return (a pointer to space for) a smaller object than
requested.
No, but it can return a pointer to a smaller object than you *tried*
to request. (But that's hardly malloc's fault.)

--
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.
Jan 3 '07 #131
av
On Tue, 02 Jan 2007 09:08:19 -0500, CBFalconer wrote:
>Richard Heathfield wrote:
>av said:
<snip>
>>it should be good to do some new type
struct NewSize_t_{
int ovf;
size_t n;
};

typedef NewSize_t_ NewSize_t;

with +-*/ defined on NewSize_t
and use it like parameter for function that now use size_t

if some overflow occur

As has been explained ad nauseam, no overflow occurs.

<snip>
>>and this resolve to the root the problem

What problem? I don't see one that can't be solved much more
simply by behavioural change than by adding a new type to the
language and then waiting 20 years for it to get implemented
across the board.

for example:

size_t overflow(size_t x, size_t y) {
size_t xmax, ymax, szmax = -1;

if (xmax && ymax) {
xmax = szmax / ymax; ymax = szmax / xmax;
if ((x xmax) || (y ymax) return 0;
return x * y;
}
return 0;
}

assuming 0 is a suitable result for an overflow.
if i want to rappresent 31 bits and not 32bits
so i have a 31 bit unsigned type

and i use the last bit of size_t (0x80000000) for rappresent overflow
assuming size_t==unsigned int and sizeof(unsigned)==32
and having an x86 cpu >= 386

/* it could do 31 bits size_t multiplication */
asm{
multix:
push edx
mov eax, [esp+ 8]
test dword[esp+12], 0x80000000
jnz .1
test eax, 0x80000000
jnz .1
xor edx, edx
mul dword[esp+12]
cmp edx, 0
je .f
..1:
mov eax, 0x80000000
..f:
pop edx
ret 8
}

unsigned _stdcall multix(unsigned a, unsigned b);
size_t multiplication(size_t x, size_t y) {return multix(x, y);}

for see if the result is not right here
if(result & 0x80000000) error;
the same for +-/ for not right results
(i.e the results that use the modulo fact)
at the end if there is some error
in some place in the calculus =>
if(result & 0x80000000) error;

possibly the above it can do for 32 bits but i have add some memory
space to size_t
>Besides which av is a troll.
Jan 3 '07 #132
Old Wolf wrote:
Mark McIntyre wrote:
>If the argument is unsigned, you can't pass a -ve value to it.

"argument" means the value passed in. In this code:

#include <stdlib.h>
int foo() { malloc(-1); }

the argument to malloc is the value -1 (of type int).

The type "size_t" w.r.t. malloc is known as the "formal parameter
type" (often the word 'formal' is dropped for convenience's sake).
No it isn't. The compiler knows that malloc wants a size_t, and so
it automatically converts that value, resulting in SIZE_T_MAX (or
whateer it is called).

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Jan 3 '07 #133
Ben Pfaff wrote:
"Old Wolf" <ol*****@inspire.net.nzwrites:
>Richard Heathfield wrote:
>>>
No, you don't get overflow with unsigned types.

Actually you do. However, the behaviour on overflow is well-defined.

C99 6.2.5p9 makes it pretty clear that the Standard takes Richard's
point of view:

A computation involving unsigned operands can never
overflow, [...]
I have code that inputs from a text stream, forbids an initial '-'
(or '+') sign (which must be handled by the calling code, if
present) and follows the C conventions for unsigned values, yet
returns an error code signifying 'overflow' or EOF or invalid
stream (no digits). This can reject such values at input. The
decision is up to the caller.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Jan 3 '07 #134
jacob navia wrote:
>
.... snip ...
>
I just can't understand why it is impossible to agree in such
an evident stuff !!!
In part it is your fault for not clearly defining meanings,
ignoring the standard, and heaving invective at those who correct
you. In some respects I think this has produced a new competive
game called 'how many Navia errors can I spot'.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Jan 3 '07 #135
"christian.bau" wrote:
CBFalconer wrote:
>What this has brought home to me is that calloc should be included
in the nmalloc package, so that the same maximum size criterion
will be applied. I.E:

void *ncalloc(size_t nmemb, size_t size) {
size_t sz;
void *p;

sz = nmemb * size;
if ((sz < nmemb) || (sz < size)) return NULL;
if (p = nmalloc(sz)) memset(p, 0, sz);
return p;
}

Just wanted to say: This will not catch many problems. For example
on a 32 bit system, nmemb = 0x10001, size = 0x10001, sz = 0x20001.
Yes. Corrected else thread.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Jan 3 '07 #136
jacob navia wrote:
christian.bau a écrit :
.... snip ...
>
lcc-win32 uses this:

void *calloc(size_t n,size_t s)
{
long long siz = (long long)n * (long long)s;
void *result;
if (siz>>32)
return 0;
result = malloc((size_t)siz);
if (result)
memset(result,0,(size_t)siz);
return result;
}
Bad. long longs can overflow, leading to undefined behaviour. No
guarantee you ever get to testing the product. Casts are always
suspicious.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Jan 3 '07 #137
Ben Pfaff wrote:
>
Keith Thompson <ks***@mib.orgwrites:
jacob navia <ja***@jacob.remcomp.frwrites:
void *calloc(size_t n,size_t s)
{
long long siz = (long long)n * (long long)s;
void *result;
if (siz>>32)
return 0;
result = malloc((size_t)siz);
if (result)
memset(result,0,(size_t)siz);
return result;
}

[...]
I wonder if "siz&~0xFFFFFFFF" might be marginally more efficient than
"siz>>32". [...]

I'd recommend "siz SIZE_MAX" as being both clear and portable.
I don't think so. Ignoring the casts, maybe

if (!(SIZE_MAX - siz)) thingsarebad();
else carryon();

I seriously doubt that most machines can generate a value larger
than SIZE_MAX.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Jan 3 '07 #138
Mark McIntyre wrote:
<ja***@jacob.remcomp.frwrote:
>This is portable to all systems where
1) long long is 64 bits
2) size_t is 32 bits

Which limits it to a fairly small subset of systems, by the way...
Which is alright, since this is a system routine and not expected
to be portable.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Jan 3 '07 #139
Nelu wrote:
>
.... snip ...
>
Why not:

void *calloc(size_t n, size_t s) {
void *result;
size_t sz;
if(SIZE_MAX/n<s) {
sz=n*s;
result=malloc(n*s);
if(result) {
memset(result,0,sz);
return result;
}
}
return NULL;
}
I think that works everywhere. I would rework it slightly to:

void *calloc(size_t n, size_t s) {
void *result;
size_t sz;

result = NULL;
if (SIZE_MAX / n < s) {
sz = n * s;
result = malloc(sz);
if (result) memset(result, 0, sz);
}
return result;
}

largely to install some blanks for readability. :-)

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Jan 3 '07 #140
Randy Howard wrote:
On Tue, 2 Jan 2007 15:49:03 -0600, christian.bau wrote
.... snip ...
>
>And most 32 bit systems have limit at 3GB or 3.5GB.

Actually it's usually 2GB, due to splitting of address space between
the kernel and user space. Some go as high as 3GB with special boot
options. However, there are hacks (outside of malloc) that allow for
what Intel calls "Physical Address Extension" (PAE) to allow systems
with Intel 32-bit processors to see memory above 4GB, sort of like the
old extended/expanded memory hacks in the DOS days. Again,
proprietary, and different APIs to use the memory from what standard C
supports.
Less than that. For a von Neuman machine the code itself has to go
somewhere, not to mention minor details such as the file system,
i/o buffers, etc.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Jan 3 '07 #141
av
On Wed, 03 Jan 2007 07:52:53 +0100, av wrote:
>On Tue, 02 Jan 2007 09:08:19 -0500, CBFalconer wrote:
>>Richard Heathfield wrote:
>>av said:
<snip>
it should be good to do some new type
struct NewSize_t_{
int ovf;
size_t n;
};

typedef NewSize_t_ NewSize_t;

with +-*/ defined on NewSize_t
and use it like parameter for function that now use size_t

if some overflow occur

As has been explained ad nauseam, no overflow occurs.

<snip>

and this resolve to the root the problem

What problem? I don't see one that can't be solved much more
simply by behavioural change than by adding a new type to the
language and then waiting 20 years for it to get implemented
across the board.

for example:

size_t overflow(size_t x, size_t y) {
size_t xmax, ymax, szmax = -1;

if (xmax && ymax) {
xmax = szmax / ymax; ymax = szmax / xmax;
if ((x xmax) || (y ymax) return 0;
return x * y;
}
return 0;
}

assuming 0 is a suitable result for an overflow.

if i want to rappresent 31 bits and not 32bits
so i have a 31 bit unsigned type

and i use the last bit of size_t (0x80000000) for rappresent overflow
assuming size_t==unsigned int and sizeof(unsigned)==32
and having an x86 cpu >= 386

/* it could do 31 bits size_t multiplication */
asm{
multix:
push edx
mov eax, [esp+ 8]
test dword[esp+12], 0x80000000
jnz .1
test eax, 0x80000000
jnz .1
xor edx, edx
mul dword[esp+12]
cmp edx, 0
je .f
.1:
mov eax, 0x80000000
.f:
pop edx
ret 8
}
*better* "size_t" is 32 bits i use
for an unsigned rappresentation unsigned 2^32-1
and the value -1==0xFFFFFFFF for error
(pseudo size_t on x86 cpu>=386)

/* it could do size_t multiplication
for numbers [0..2^32-2]
*/
asm{
multix:
push edx
mov eax, [esp+ 8]
cmp [esp+12], -1
je .1
cmp eax, -1
je .f
xor edx, edx
mul dword[esp+12]
cmp edx, 0
je .f
..1:
mov eax, -1
..f:
pop edx
ret 8
}

asm{
addsize:
mov eax, [esp+ 4]
cmp [esp+8], -1
je .1
cmp eax, -1
je .f
add eax, [esp+8]
jnc .f
..1:
mov eax, -1
..f:
pop edx
ret 8
}

asm{
subsize:
mov eax, [esp+ 4]
cmp [esp+8], -1
je .1
cmp eax, -1
je .f
sub eax, [esp+8]
j>= .f
..1:
mov eax, -1
..f:
pop edx
ret 8
}

unsigned _stdcall multix(unsigned a, unsigned b);
size_t multiplication(size_t x, size_t y) {return multix(x, y);}

unsigned _stdcall addsize(unsigned a, unsigned b);
size_t addx(size_t x, size_t y) {return addsize(x, y);}

unsigned _stdcall subsize(unsigned a, unsigned b);
size_t subx(size_t x, size_t y) {return subsize(x, y);}

etc
>>Besides which av is a troll.
who is the troll?
Jan 3 '07 #142
av
On Wed, 03 Jan 2007 10:33:52 +0100, av wrote:
>On Wed, 03 Jan 2007 07:52:53 +0100, av wrote:
>>On Tue, 02 Jan 2007 09:08:19 -0500, CBFalconer wrote:
>>>Richard Heathfield wrote:
av said:
>*better* "size_t" is 32 bits i use
for an unsigned rappresentation unsigned 2^32-1
and the value -1==0xFFFFFFFF for error
(pseudo size_t on x86 cpu>=386)

/* it could do size_t multiplication
for numbers [0..2^32-2]
*/
asm{
multix:
push edx
mov eax, [esp+ 8]
cmp [esp+12], -1
je .1
cmp eax, -1
je .f
xor edx, edx
mul dword[esp+12]
cmp edx, 0
je .f
.1:
mov eax, -1
.f:
pop edx
ret 8
}

asm{
addsize:
mov eax, [esp+ 4]
cmp [esp+8], -1
je .1
cmp eax, -1
je .f
add eax, [esp+8]
jnc .f
.1:
mov eax, -1
.f:
pop edx
ret 8
}

asm{
subsize:
mov eax, [esp+ 4]
cmp [esp+8], -1
je .1
cmp eax, -1
je .f
sub eax, [esp+8]
j>= .f
.1:
mov eax, -1
.f:
pop edx
ret 8
}

unsigned _stdcall multix(unsigned a, unsigned b);
size_t operator*(size_t x, size_t y) {return multix(x, y);}
>unsigned _stdcall addsize(unsigned a, unsigned b);
size_t operator+(size_t x, size_t y) {return addsize(x, y);}
>unsigned _stdcall subsize(unsigned a, unsigned b);
size_t operator-(size_t x, size_t y) {return subsize(x, y);}
etc
size_t result, a, b, c, d, h;
.....
result=a*b+c*d-h;

i forget to say it there is some overflow in some place
if(result==-1) error;

but this change the definiton of size_t.

your dear c standard is wrong in the definition on size_t

is there someone agree with me?
>>>Besides which av is a troll.

who is the troll?
Jan 3 '07 #143
av said:

<snip>
your dear c standard is wrong in the definition on size_t

is there someone agree with me?
Unlikely, since you're wrong. The C Standard correctly defines size_t.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jan 3 '07 #144
av
On Wed, 03 Jan 2007 10:33:52 +0100, av wrote:
>On Wed, 03 Jan 2007 07:52:53 +0100, av wrote:
>>On Tue, 02 Jan 2007 09:08:19 -0500, CBFalconer wrote:
>>>Richard Heathfield wrote:
av said:
>*better* "size_t" is 32 bits i use
for an unsigned rappresentation unsigned 2^32-1
and the value -1==0xFFFFFFFF for error
(pseudo size_t on x86 cpu>=386)

/* it could do size_t multiplication
for numbers [0..2^32-2]
*/
asm{
multix:
push edx
mov eax, [esp+ 8]
cmp [esp+12], -1
je .1
cmp eax, -1
je .f
xor edx, edx
mul dword[esp+12]
cmp edx, 0
je .f
.1:
mov eax, -1
.f:
pop edx
ret 8
}

asm{
addsize:
mov eax, [esp+ 4]
cmp [esp+8], -1
je .1
cmp eax, -1
je .f
add eax, [esp+8]
jnc .f
.1:
mov eax, -1
.f:
pop edx
ret 8
}

asm{
subsize:
mov eax, [esp+ 4]
cmp [esp+8], -1
je .1
cmp eax, -1
je .f
sub eax, [esp+8]
j>= .f
.1:
mov eax, -1
.f:
pop edx
ret 8
}

unsigned _stdcall multix(unsigned a, unsigned b);
size_t operator*(size_t x, size_t y) {return multix(x, y);}
>unsigned _stdcall addsize(unsigned a, unsigned b);
size_t operator+(size_t x, size_t y) {return addsize(x, y);}
>unsigned _stdcall subsize(unsigned a, unsigned b);
size_t operator-(size_t x, size_t y) {return subsize(x, y);}
etc
size_t result, a, b, c, d, h;
.....
result=a*b+c*d-h;

i forget to say it there is some overflow in some place
if(result==-1) error;

but this change the definiton of size_t.

your dear c standard is wrong in the definition on size_t

is there someone agree with me?
so where are answers?
do you like doublepost? :)
>>>Besides which av is a troll.

who is the troll?
Jan 3 '07 #145
av
On Wed, 03 Jan 2007 09:57:52 +0000, Richard Heathfield wrote:
>av said:

<snip>
>your dear c standard is wrong in the definition on size_t

is there someone agree with me?

Unlikely, since you're wrong. The C Standard correctly defines size_t.
C Standard is wrong on that
you're hardly wrong
Jan 3 '07 #146
av said:

<snip>
your dear c standard is wrong in the definition on size_t
Not according to the C Standard.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jan 3 '07 #147
av said:
On Wed, 03 Jan 2007 09:57:52 +0000, Richard Heathfield wrote:
>The C Standard correctly defines size_t.

C Standard is wrong on that
No, it isn't.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jan 3 '07 #148
av wrote:
On Wed, 03 Jan 2007 09:57:52 +0000, Richard Heathfield wrote:
>>av said:

<snip>
>>your dear c standard is wrong in the definition on size_t

is there someone agree with me?

Unlikely, since you're wrong. The C Standard correctly defines size_t.

C Standard is wrong on that
Since it's the defining document, what do you mean by "wrong"
here?

--
Chris "hopefully not Pyecroft" Dollin
"Who are you? What do you want?" /Babylon 5/

Jan 3 '07 #149
On Wed, 03 Jan 2007 01:47:00 +0100, jacob navia
<ja***@jacob.remcomp.frwrote:
>Ben Pfaff a écrit :
>jacob navia <ja***@jacob.remcomp.frwrites:
>>>When the result "cannot be represented by the resulting
integer type" ... If this is not overflow I do not know
what overflow actually means!!!!


Based on its use in the Standard, I'd guess that the meaning of
overflow in the committee's minds is an exceptional condition
that yields undefined behavior. Because out-of-range unsigned
values are not treated exceptionally and do not yield undefined
behavior, they are not examples of overflow under this
definition. Indeed, the Standard uses "integer overflow" as its
stock example of undefined behavior, not "signed integer
overflow", because "unsigned integer overflow" is a contradiction
in terms according to this definition.

Here is part of what the Rationale says about integer overflow.
I believe that it supports my position:

The keyword unsigned is something of a misnomer, suggesting
as it does in arithmetic that it is non-negative but
capable of overflow. The semantics of the C type unsigned
is that of modulus, or wrap-around, arithmetic for which
overflow has no meaning. The result of an unsigned
arithmetic operation is thus always defined, whereas the
result of a signed operation may be undefined.

Yes, I know that, and I agree that the semantics of unsigned is
wrap around. What I am saying is that when "the result cannot be
represented" and this wrap around semantics reduces the result,
this reduced result is mathematically WRONG in the sense of the USUAL
multiplication operation.

PHEW!!!!

Specifically when I use the malloc (p * sizeof *p) "idiom"
even if the semantics are well defined this is NOT what I
inteded with that multiplication!!!!
Your problem is that you should neither be using nor advocating the
use of malloc() if "p * sizeof *p" results in a mathematical value
that is greater than (or arguably even light years close to) the
maximum value that can be represented by size_t. Nor should you be
using or advocating the use of malloc() if the size of memory you need
to "allocate" is known at compile-time.

<anecdotal>
In my life, I've seen more misuses of malloc() than I've seen
legitimate uses of malloc(). One of the misuses of malloc() I've seen
goes something like this snippet (I'm not kidding):

char *p;
assert(p = (char*)malloc(sizeof(char)));
*p = 1;
</anecdotal>

Your original example was ostensively contrived, and the astute
observer may ask the question "why not declare the storage as static
and not even use malloc()?"

To which you may have replied something to the tune of: "but I don't
know the size of memory I need to allocate at compile-time".

To which the the astute observer may have replied: "so use malloc(),
and make sure that the size requested is not abnormally unreasonable."

To which you may have replied: "I see."

Or not.

There are a couple of more points to consider juxtaposing against the
arguments you have proffered so far in this thread:

1. "overflow" of a signed value results in undefined behavior.
2. malloc() is not the only function covered by the spirit of your
arguments. You must consider the following functions, inter alia,
also:

void qsort(void*, size_t, size_t, int (*)(const void*, const void*));
void* memchr(const void*, int, size_t);
int memcmp(const void*, const void*, size_t);
void* memcpy(void*, const void*, size_t);
void* memmove(void*, const void*, size_t);
void* memset(void*, int, size_t);
size_t strlen(const char*);
int strncmp(const char*, const char*, size_t);
char* strncpy(char*, const char*, size_t);
size_t fread(void*, size_t, size_t, FILE*);
size_t frite(const void*, size_t, size_t, FILE*);

--
jay
Jan 3 '07 #150

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

Similar topics

1
by: Adam Warner | last post by:
Hi all! When dealing with dynamically adjusted objects are you ever concerned that you'll double the requested size of the object and overflow size_t so that the requested size e.g. becomes...
34
by: Alawna | last post by:
Hi, i was reading a chapter about c pointers in "c++builder complete reference" and it is said there that malloc returns a pointer to the start of the memory allocated but i see the prototype of...
40
by: Confused User | last post by:
I am curious what the origins of size_t are. I see that it is usually typedef'd to be the native integer size of a particular machine. I also see that routines like strncpy(char *t, const char *s,...
18
by: rayw | last post by:
I used to believe that size_t was something to do with integral types, and the std. Something along the lines of .. a char is 8 bits, a int >= a char a long >= int
12
by: Alex Vinokur | last post by:
Why was the size_t type defined in compilers in addition to unsigned int/long? When/why should one use size_t? Alex Vinokur email: alex DOT vinokur AT gmail DOT com...
20
by: ramasubramanian.rahul | last post by:
hi folks i have a peculiar problem. i have to allocate more than size_t consequtive bytes on a system . after i do a malloc .. i am unable to do a realloc because it takes size_t as a new size...
13
by: sam_cit | last post by:
Hi Everyone, I was looking at the function prototype of malloc() function in stdlib.h and i found that to be, void *malloc(size_t size); so what is size_t is it a pre-defined typedef to...
73
by: Yevgen Muntyan | last post by:
Hey, I was reading C99 Rationale, and it has the following two QUIET CHANGE paragraphs: 6.5.3.4: "With the introduction of the long long and extended integer types, the sizeof operator may...
409
by: jacob navia | last post by:
I am trying to compile as much code in 64 bit mode as possible to test the 64 bit version of lcc-win. The problem appears now that size_t is now 64 bits. Fine. It has to be since there are...
21
by: pereges | last post by:
For eg : struct mesh { size_t nvert; /* number of vertices */ size_t ntri; /* number of triangles */ ..... }; The reason I want to use size_t is because I've read that it is
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
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
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
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.