size_t or int for malloc-type functions?

C

Chris Dollin

Spiros said:
That's not what "onto" means. Just by virtue of the fact
that + and * are functions we know that for every pair
(a,b) there's going to be an image under + and an image
under * ie a+b and a*b are both going to be defined.

Functions don't have to be total: consider, for example,
division.
 
C

Clark S. Cox III

Douglas said:
I'd like to request that people please not assume that -1
is represented by all 1 value bits.

Where do you see that assumption?
((size_t)0 - 1) is one nice way to get all 1 value bits of
the desired width. You could also use ~(size_t)0.

How could ((size_t)0 - 1) or (~(size_t)0) differ in any way from
((size_t)-1)?
 
F

Francois Grieu

((size_t)0 - 1) is one nice way to get all 1 value bits of
the desired width. You could also use ~(size_t)0.

How could ((size_t)0 - 1) or (~(size_t)0) differ in any way from
((size_t)-1)?[/QUOTE]

Because -1 is of type signed int and thus it's cast
to size_t undefined, is not it ?


François Grieu
 
R

Richard Heathfield

Francois Grieu said:
How could ((size_t)0 - 1) or (~(size_t)0) differ in any way from
((size_t)-1)?

Because -1 is of type signed int and thus it's cast
to size_t undefined, is not it ?[/QUOTE]

Why?

The Standard has this to say on implicit and explicit conversions, in
6.3.1.3 Signed and Unsigned Integers:

"Otherwise, if the new type is unsigned, the value is converted by
repeatedly adding or subtracting one more than the maximum value that can
be represented in the new type until the value is in the range of the new
type."

That looks pretty defined to me. What am I missing?
 
C

Clark S. Cox III

Francois said:
How could ((size_t)0 - 1) or (~(size_t)0) differ in any way from
((size_t)-1)?

Because -1 is of type signed int and thus it's cast
to size_t undefined, is not it ?[/QUOTE]

No, it most certainly is not. When a signed integer is converted to an
unsigned integer (like size_t), the value is converted according to
modulo arithmetic (i.e. -1, becomes the maximum possible value, -2
becomes one less than the maximum value, etc.)
 
P

Peter Nilsson

Clark said:
Where do you see that assumption?


How could ((size_t)0 - 1) or (~(size_t)0) differ in any way from
((size_t)-1)?

They could differ (potentially for the worse) if size_t was subject
to integral promotion. Though you're unlikely to find an implementation
where that is the case.
 
J

Jun Woong

Peter said:
They could differ (potentially for the worse) if size_t was subject
to integral promotion. Though you're unlikely to find an implementation
where that is the case.

Interestingly, if size_t is subject to integral promotion, only
((size_t)-1) works correctly.


--
Jun, Woong (woong at icu.ac.kr)
Samsung Electronics Co., Ltd.

``All opinions expressed are mine, and do not represent
the official opinions of any organization.''
 
C

Clark S. Cox III

Peter said:
They could differ (potentially for the worse) if size_t was subject
to integral promotion. Though you're unlikely to find an implementation
where that is the case.

Ahh, I hadn't thought of that. But, as you indicated, this actually
argues that (size_t)-1 is the "correct" construct; in the presence of
integral promotion, it is the only on that still yields the maximum
possible size_t value.
 
S

Spiros Bousbouras

Chris said:
Functions don't have to be total: consider, for example,
division.

I think in recursion theory you may have a distinction
between total and non-total functions but in every other
branch of mathematics I've seen and certainly in algebra
you don't ; function means "total" function. In particular,
every textbook on set theory will tell you that a function
from a set A into a set B is a subset of AxB such that for
*every* a in A there is exactly one b in B such that (a,b) is
in f. Algebra uses the set-theoretic definition of a function.
 
C

Chris Dollin

Spiros said:
I think in recursion theory you may have a distinction
between total and non-total functions but in every other
branch of mathematics I've seen and certainly in algebra
you don't ; function means "total" function. In particular,
every textbook on set theory will tell you that a function
from a set A into a set B is a subset of AxB such that for
*every* a in A there is exactly one b in B such that (a,b) is
in f. Algebra uses the set-theoretic definition of a function.

Division.
 
D

Douglas A. Gwyn

Clark S. Cox III said:
Ahh, I hadn't thought of that. But, as you indicated, this actually
argues that (size_t)-1 is the "correct" construct; in the presence of
integral promotion, it is the only on that still yields the maximum
possible size_t value.

Actually I missed that the promotion and conversion rules would
produce the right result for (size_t)-1. However, why doesn't
~(size_t)0 work?
 
G

Guest

Douglas said:
Actually I missed that the promotion and conversion rules would
produce the right result for (size_t)-1. However, why doesn't
~(size_t)0 work?

If size_t is promoted to int, ~(size_t)0 is equivalent to
~(int)(size_t)0, or simply ~0. It might have been nice if ~'s operand
didn't undergo the integer promotions, but it does.
 
C

CBFalconer

Douglas A. Gwyn said:
Actually I missed that the promotion and conversion rules would
produce the right result for (size_t)-1. However, why doesn't
~(size_t)0 work?

Because that is sensitive to the storage format. It may be 2's
complement, 1's complement, or sign-magnitude. ~(size_t)0 will
only work for 2's complement, thus not portable.
 
G

Guest

CBFalconer said:
Because that is sensitive to the storage format. It may be 2's
complement, 1's complement, or sign-magnitude. ~(size_t)0 will
only work for 2's complement, thus not portable.

Depending on how you use it, ~(size_t)0 is not guaranteed to work for
2's complement. If size_t promotes to signed int, ~(size_t)0 has type
int and value -1. You don't get SIZE_MAX unless you then convert /that/
to size_t.
 
C

Clark S. Cox III

Douglas said:
Actually I missed that the promotion and conversion rules would
produce the right result for (size_t)-1. However, why doesn't
~(size_t)0 work?

Because, if size_t promotes to int, applying the '~' operator will
provide a result that is a (signed) int. This int will *only* have the
value of -1 on twos-compliment machines; converting *that* -1 back to
size_t will result in the correct value

Works on twos-complement machines:
size_t foo = (size_t)~(size_t)0;
size_t bar = (size_t)~0;

Works on all machines:
size_t baz = (size_t)-1;
 
D

Douglas A. Gwyn

CBFalconer said:
Because that is sensitive to the storage format. It may be 2's
complement, 1's complement, or sign-magnitude. ~(size_t)0 will
only work for 2's complement, thus not portable.

No, that was my complaint about -1, which I was thinking
for ones-complement would have produced x...FFFFFE rather
than the desired x...FFFFFF A bitwise complement of an
all-0 bit pattern should give all 1 bits.
 
C

Clark S. Cox III

Douglas said:
No, that was my complaint about -1, which I was thinking
for ones-complement would have produced x...FFFFFE rather
than the desired x...FFFFFF

This is not the case. We are guaranteed that *any* signed "-1", when
converted to an unsigned type will be the maximum possible value for
that type. The representation doesn't matter, only the value. Period.
 
C

CBFalconer

Douglas A. Gwyn said:
No, that was my complaint about -1, which I was thinking
for ones-complement would have produced x...FFFFFE rather
than the desired x...FFFFFF A bitwise complement of an
all-0 bit pattern should give all 1 bits.

But the conversion from int to unsigned is specified to make that
correction. A negative value doesn't fit into the range of an
unsigned type, so the standard specifies that it is corrected by
adding SIZE_MAX+1 until the result is in range. Works every time.
 
C

Cesar Rabak

Steve Summit escreveu:
With perfect 20/20 hindsight I agree, but...



I'd be much more inclined to agree with this if the Standard
explicitly said

If the product nmemb * size cannot be represented as a
size_t, the calloc function returns NULL.

I wish the Standard did say that. This is really a grey area, a
longstanding source of bugs and misunderstanding. (See e.g. the
related c.l.c. FAQ 7.16.)

Without the explicit statement (and as the arguments presented by
several knowledgeable posters in this thread prove), I think an
implementor could be excused for assuming that the Standard's
intent was

If the product nmemb * size cannot be represented as a
size_t, the behavior is undefined.

...although since the Standard doesn't say *that* explicitly,
either, it's sort of doubly or meta undefined!

I disagree that we accept 'meta undefinedness' as conceptually Standard
compliant.

As the Standard _requires_ the memory allocated by calloc be nmemb
elements of size size, and zero all of it, I think a better
interpretation would be that non returning that [amount of memory] is
not compliant.

The issue FAQ 7.16 covers malloc, when the programmer makes the product,
not the internal function implementation as calloc.
 
S

Spiros Bousbouras

Chris said:
Division.

Which operation do you mean by division ? If you
mean for example the usual a/b where a,b are real
numbers then it's not an operation in the formal
sense of the word although informally it may be called
such.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,817
Latest member
AdalbertoT

Latest Threads

Top