468,771 Members | 1,922 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,771 developers. It's quick & easy.

Origin of size_t? Curious.

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, size_t n).

So, is size_t the native size of the machine or used to describe the actual
size of something (like the len of a string copy).

If it is named because it designates the size of something, then could I
still have more than 65535 bytes of something. If so why is that called
size_t.

I understand that it is just an int, but I don't understand the name. I can
have a size that is larger than an int. Perhaps I could store the size of
something in long? Wow?!?!?!

What the heck are the origins for the name?

Elvis

Nov 15 '05 #1
40 2121
Confused User affirmed:

| 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, size_t n).
|
| So, is size_t the native size of the machine or used to describe
| the actual size of something (like the len of a string copy).
|
| If it is named because it designates the size of something, then
| could I still have more than 65535 bytes of something. If so why is
| that called size_t.
|
| I understand that it is just an int, but I don't understand the
| name. I can have a size that is larger than an int. Perhaps I could
| store the size of something in long? Wow?!?!?!
|
| What the heck are the origins for the name?

A size_t is large enough to represent the largest number of
<something> possible to the implementation. It need not be an int and,
in fact, it'd probably make more sense for it to be a long int. An
unsigned long would seem even better; but would prevent returning
(size_t) -1 for an error value.

Why size_t at all? So that we can recompile libraries and applications
for new systems (with different size size_t values) by modifying only
the size_t definition.

--
Morris Dovey
DeSoto Solar
DeSoto, Iowa USA
http://www.iedu.com/DeSoto
Nov 15 '05 #2
On 2005-06-22 21:29:29 -0400, "Morris Dovey" <mr*****@iedu.com> said:
A size_t is large enough to represent the largest number of
<something> possible to the implementation. It need not be an int and,
in fact, it'd probably make more sense for it to be a long int. An
unsigned long would seem even better; but would prevent returning
(size_t) -1 for an error value.


You are mistaken, size_t is never signed, so it cannot possibly be int
or long int.
--
Clark S. Cox, III
cl*******@gmail.com

Nov 15 '05 #3
>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, size_t n).

So, is size_t the native size of the machine or used to describe the actual
size of something (like the len of a string copy).

If it is named because it designates the size of something, then could I
still have more than 65535 bytes of something.
Really? How? malloc() takes a size_t as an argument, so you can't
malloc() anything bigger. And if you can't take sizeof(struct foo),
it isn't necessary for it to allow your declaration of struct foo
that exceeds the limits of a size_t. The same applies to large arrays.
I understand that it is just an int, but I don't understand the name. I can
It's not an int. Unsigned int, maybe. Unsigned long is more likely.
have a size that is larger than an int. Perhaps I could store the size of
something in long? Wow?!?!?!


Gordon L. Burditt
Nov 15 '05 #4
Morris Dovey wrote:
Confused User affirmed:

| 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, size_t n).
|
| So, is size_t the native size of the machine or used to describe
| the actual size of something (like the len of a string copy).
|
| If it is named because it designates the size of something, then
| could I still have more than 65535 bytes of something. If so why is
| that called size_t.
|
| I understand that it is just an int, but I don't understand the
| name. I can have a size that is larger than an int. Perhaps I could
| store the size of something in long? Wow?!?!?!
|
| What the heck are the origins for the name?

A size_t is large enough to represent the largest number of
<something> possible to the implementation. It need not be an int and,
in fact, it'd probably make more sense for it to be a long int. An
unsigned long would seem even better; but would prevent returning
(size_t) -1 for an error value.


size_t must be an unsigned integer type and thus can never represent a
negative value. (size_t) -1 would be equivalent to SIZE_MAX.

Robert Gamble

Nov 15 '05 #5
Clark S. Cox III affirmed:

| On 2005-06-22 21:29:29 -0400, "Morris Dovey" <mr*****@iedu.com>
| said:
|| A size_t is large enough to represent the largest number of
|| <something> possible to the implementation. It need not be an int
|| and, in fact, it'd probably make more sense for it to be a long
|| int. An unsigned long would seem even better; but would prevent
|| returning (size_t) -1 for an error value.
|
| You are mistaken, size_t is never signed, so it cannot possibly be
| int or long int.

Clark...

You're absolutely right. In 7.17.2 it's spec'd as "the unsigned
integer type of the result of the *sizeof* operator".

I should've looked before posting. Thanks!

--
Morris Dovey
DeSoto Solar
DeSoto, Iowa USA
http://www.iedu.com/DeSoto/
Nov 15 '05 #6
"Morris Dovey" <mr*****@iedu.com> wrote in message
news:2r****************@news.uswest.net...
You're absolutely right. In 7.17.2 it's spec'd as "the unsigned
integer type of the result of the *sizeof* operator".


Yep. Its origins lie in the old <std.h> header we developed at
Whitesmiths, Ltd. in the late 1970s. We used the typedef BYTES
as the type of sizeof, to be sure we could count all the bytes
in the largest declarable (or allocatable) object. X3J11 chose
size_t to follow the *_t convention that had begun to creep up
in Posix.

HTH,

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Nov 15 '05 #7
Gordon Burditt <go***********@burditt.org> wrote:
If it is named because it designates the size of something, then could I
still have more than 65535 bytes of something.
Really? How? malloc() takes a size_t as an argument, so you can't
malloc() anything bigger. And if you can't take sizeof(struct foo),
it isn't necessary for it to allow your declaration of struct foo
that exceeds the limits of a size_t. The same applies to large arrays.


I don't understand. Where exactly is it written that `size_t' must
be able to cover sizes of all types? All I can find is that `size_t'
is the type returned by `sizeof' operator. Does it mean that
implementations must forbid types whose size cannot be taken?
Is it a CV, or UB?

As for allocated objects, you can't create an object larger than
SIZE_MAX with malloc(). But an implementation might have its own
allocation function:
void *hugealloc(unsigned long hi, unsigned long lo);
Would such an implementation be non-conforming?

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 15 '05 #8
S.Tobias wrote:
I don't understand. Where exactly is it written that `size_t' must
be able to cover sizes of all types? All I can find is that `size_t'
is the type returned by `sizeof' operator. Does it mean that
implementations must forbid types whose size cannot be taken?


N869
6.5.3.4 The sizeof operator
[#2] The sizeof operator yields the size (in bytes) of its
operand, which may be an expression or the parenthesized
name of a type

If the size cannot be taken, then how can sizeof do
what it's supposed to do?

--
pete
Nov 15 '05 #9
On 2005-06-23 08:21:32 -0400, "S.Tobias"
<si***@FamOuS.BedBuG.pAlS.INVALID> said:
Gordon Burditt <go***********@burditt.org> wrote:
If it is named because it designates the size of something, then could I
still have more than 65535 bytes of something.
Really? How? malloc() takes a size_t as an argument, so you can't malloc() anything bigger. And if you can't take sizeof(struct foo),
it isn't necessary for it to allow your declaration of struct foo
that exceeds the limits of a size_t. The same applies to large arrays.

I don't understand. Where exactly is it written that `size_t' must be
able to cover sizes of all types? All I can find is that `size_t'
is the type returned by `sizeof' operator. Does it mean that
implementations must forbid types whose size cannot be taken?

Well, sizeof cannot possibly result in any value larger than SIZE_MAX,
and sizeof has to work with any type, it logically follows that no type
can require more than SIZE_MAX bytes.

Is it a CV, or UB?
I too can't tell if it would be a CV or UB. I wonder if a conforming
implementation would be required to issue a diagnostic on the following
structure:
struct Foo
{
char array1[SIZE_MAX];
char array2[SIZE_MAX];
char array3[SIZE_MAX];
};

Gcc certianly does, but I wonder if it's required to do so.

test.c:6: error: size of array ‘array1’ is too large
test.c:7: error: size of array ‘array2’ is too large
test.c:8: error: size of array ‘array3’ is too large

However, I've just noticed that if I make the size of the individual
arrays small enough for gcc, it surprisingly *does not* warn about the
structure itself, and the result of sizeof seems to have wrapped around
as unsigned integers are wont to do):

[littleclark2:~] clarkcox% cat test.c
#include <stdlib.h>
#include <stdio.h>

struct Foo
{
char array1[SIZE_MAX / 2];
char array2[SIZE_MAX / 2];
char array3[SIZE_MAX / 2];
};

int main()
{
printf("SIZE_MAX: %zd\nsizeof(struct Foo): %zd\n", (size_t)SIZE_MAX,
sizeof(struct Foo));
return 0;
}
[littleclark2:~] clarkcox% gcc test.c -ansi -pedantic
[littleclark2:~] clarkcox% ./a.out
SIZE_MAX: 4294967295
sizeof(struct Foo): 2147483645
[littleclark2:~] clarkcox%

This seems dangerous to my mind. Someone attempting to do the following
allocation:

strict Foo *foo = malloc(sizeof *foo);

may find that malloc "succeeds", but only allocates about 1/3 of the
memory required to contain an instance of struct Foo.
As for allocated objects, you can't create an object larger than SIZE_MAX with malloc(). But an implementation might have its own
allocation function:
void *hugealloc(unsigned long hi, unsigned long lo);
Would such an implementation be non-conforming?

No need to look to a hypothetical implementation, I would imagine that
such a situation could arise with calloc (assuming that it doesn't
return NULL, which seems exceedingly likely on sane implementations):


calloc(2, SIZE_MAX);

Either way, the result has a type of (void*), and there is no way to
apply sizeof to what it points to.
--
Clark S. Cox, III
cl*******@gmail.com

Nov 15 '05 #10
pete <pf*****@mindspring.com> wrote:
S.Tobias wrote:
I don't understand. Where exactly is it written that `size_t' must
be able to cover sizes of all types? All I can find is that `size_t'
is the type returned by `sizeof' operator. Does it mean that
implementations must forbid types whose size cannot be taken?
N869
6.5.3.4 The sizeof operator
[#2] The sizeof operator yields the size (in bytes) of its
operand, which may be an expression or the parenthesized
name of a type If the size cannot be taken, then how can sizeof do
what it's supposed to do?


So what should a compiler do? Should it reject the code which
contains a declaration of type that is too large, or is it UB
applying `sizeof' to such type?

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 15 '05 #11
Clark S. Cox III wrote:
On 2005-06-23 08:21:32 -0400, "S.Tobias"
<si***@FamOuS.BedBuG.pAlS.INVALID> said:
Gordon Burditt <go***********@burditt.org> wrote:
If it is named because it designates the size of something, then could I
still have more than 65535 bytes of something.
Really? How? malloc() takes a size_t as an argument, so you can't
malloc() anything bigger. And if you can't take sizeof(struct foo),
it isn't necessary for it to allow your declaration of struct foo
that exceeds the limits of a size_t. The same applies to large arrays.

I don't understand. Where exactly is it written that `size_t' must be
able to cover sizes of all types? All I can find is that `size_t'
is the type returned by `sizeof' operator. Does it mean that
implementations must forbid types whose size cannot be taken?

Well, sizeof cannot possibly result in any value larger than SIZE_MAX,
and sizeof has to work with any type, it logically follows that no type
can require more than SIZE_MAX bytes.

Is it a CV, or UB?

I too can't tell if it would be a CV or UB. I wonder if a conforming
implementation would be required to issue a diagnostic on the following
structure:


struct Foo
{
char array1[SIZE_MAX];
char array2[SIZE_MAX];
char array3[SIZE_MAX];
};

Gcc certianly does, but I wonder if it's required to do so.

test.c:6: error: size of array 'array1' is too large
test.c:7: error: size of array 'array2' is too large
test.c:8: error: size of array 'array3' is too large


See Defect Report #266 entitled "overflow of sizeof" which discusses
just this scenerio using the similiar example:

char x [SIZE_MAX / 2][SIZE_MAX / 2];
size_t s = sizeof x;

The committe response was that there are multiple acceptable
interpretations of the produced behavior and that:

"The program is not strictly conforming because it exceeds an
environmental limit. If the implementation generates code, there is no
requirement for a diagnostic. In the event that sizeof is called on the
object, a diagnostic can be issued, but is not required."

You can find the full report at:
http://www.open-std.org/jtc1/sc22/wg...ocs/dr_266.htm

Robert Gamble

Nov 15 '05 #12
S.Tobias wrote:

pete <pf*****@mindspring.com> wrote:
S.Tobias wrote:
I don't understand. Where exactly is it written that `size_t' must
be able to cover sizes of all types? All I can find is that `size_t'
is the type returned by `sizeof' operator. Does it mean that
implementations must forbid types whose size cannot be taken?

N869
6.5.3.4 The sizeof operator
[#2] The sizeof operator yields the size (in bytes) of its
operand, which may be an expression or the parenthesized
name of a type

If the size cannot be taken, then how can sizeof do
what it's supposed to do?


So what should a compiler do? Should it reject the code which
contains a declaration of type that is too large, or is it UB
applying `sizeof' to such type?


My compiler accepts the oversized declaration,
I just can't use it anywhere.

When I uncomment array_5, i get:
new.c(11) : error C2089: 'structure' : 'struct' too large

/* BEGIN new.c */

#include <stdio.h>

struct structure {
char array_0[(size_t)-1 / 5];
char array_1[(size_t)-1 / 5];
char array_2[(size_t)-1 / 5];
char array_3[(size_t)-1 / 5];
char array_4[(size_t)-1 / 5];
/* char array_5[(size_t)-1 / 5];*/
};

int main(void)
{
printf("sizeof(array) is %lu\n",
(long unsigned)sizeof(struct structure));
return 0;
}

/* END new.c */

--
pete
Nov 15 '05 #13
In article <42***********@mindspring.com>, pf*****@mindspring.com says...
S.Tobias wrote:

pete <pf*****@mindspring.com> wrote:
S.Tobias wrote:

> I don't understand. Where exactly is it written that `size_t' must
> be able to cover sizes of all types? All I can find is that `size_t'
> is the type returned by `sizeof' operator. Does it mean that
> implementations must forbid types whose size cannot be taken?

N869
6.5.3.4 The sizeof operator
[#2] The sizeof operator yields the size (in bytes) of its
operand, which may be an expression or the parenthesized
name of a type

If the size cannot be taken, then how can sizeof do
what it's supposed to do?


So what should a compiler do? Should it reject the code which
contains a declaration of type that is too large, or is it UB
applying `sizeof' to such type?


My compiler accepts the oversized declaration,
I just can't use it anywhere.

When I uncomment array_5, i get:
new.c(11) : error C2089: 'structure' : 'struct' too large

/* BEGIN new.c */

#include <stdio.h>

struct structure {
char array_0[(size_t)-1 / 5];


So you have -1, cast to an unsigned (and probably very large) value, then
divided by 5, yielding a still quite large value. Several such arrays
are probably far too large for your implementation to handle this way,
regardless of size_t. Try just putting in

char array_0[1000000];
and repeat that five times and watch what happens. More than a few
compilers will cough up blood on the first one.

This is a different limitation, as there is no guarantee that you
can statically declare arrays which add up to the max value for
size_t, if that's what you are trying to achieve by having five of
them.

Imagine you did manage to consume all of "size_t's range" with
arrays of char, where would your code run?

--
Randy Howard (2reply remove FOOBAR)
"I don't really care about being right you know,
I just care about success." --Steve Jobs
Nov 15 '05 #14
In article <3i************@individual.net>,
"S.Tobias" <si***@FamOuS.BedBuG.pAlS.INVALID> wrote:
pete <pf*****@mindspring.com> wrote:
S.Tobias wrote:
I don't understand. Where exactly is it written that `size_t' must
be able to cover sizes of all types? All I can find is that `size_t'
is the type returned by `sizeof' operator. Does it mean that
implementations must forbid types whose size cannot be taken?

N869
6.5.3.4 The sizeof operator
[#2] The sizeof operator yields the size (in bytes) of its
operand, which may be an expression or the parenthesized
name of a type

If the size cannot be taken, then how can sizeof do
what it's supposed to do?


So what should a compiler do? Should it reject the code which
contains a declaration of type that is too large, or is it UB
applying `sizeof' to such type?


It doesn't say anywhere that it is undefined behavior. 6.5.3.4 clearly
says what the compiler has to do. If the compiler cannot do what it has
to do, then it should better tell the user.

(The correct solution is for the compiler not to allow the definition of
any type that is so large that sizeof cannot yield the correct result as
required).
Nov 15 '05 #15
Randy Howard wrote:

In article <42***********@mindspring.com>,
pf*****@mindspring.com says...
S.Tobias wrote:
So what should a compiler do? Should it reject the code which
contains a declaration of type that is too large, or is it UB
applying `sizeof' to such type?
My compiler accepts the oversized declaration,
I just can't use it anywhere.

Imagine you did manage to consume all of "size_t's range" with
arrays of char, where would your code run?


The question is
"Should it reject the code which contains a declaration
of type that is too large, or is it UB applying `sizeof' to such type?"

My compiler allows the declaration, but not the usage of the type.

I don't really know what a compiler is supposed to do
with an oversized declaration.

--
pete
Nov 15 '05 #16
Christian Bau wrote:

In article <3i************@individual.net>,
"S.Tobias" <si***@FamOuS.BedBuG.pAlS.INVALID> wrote:
pete <pf*****@mindspring.com> wrote:
S.Tobias wrote:

> I don't understand. Where exactly is it written that `size_t' must
> be able to cover sizes of all types? All I can find is that `size_t'
> is the type returned by `sizeof' operator. Does it mean that
> implementations must forbid types whose size cannot be taken?
N869
6.5.3.4 The sizeof operator
[#2] The sizeof operator yields the size (in bytes) of its
operand, which may be an expression or the parenthesized
name of a type

If the size cannot be taken, then how can sizeof do
what it's supposed to do?


So what should a compiler do? Should it reject the code which
contains a declaration of type that is too large, or is it UB
applying `sizeof' to such type?


It doesn't say anywhere that it is undefined behavior. 6.5.3.4 clearly
says what the compiler has to do.
If the compiler cannot do what it has
to do, then it should better tell the user.


No.
If the compiler can't do what it is supposed to do,
then it is not a conforming C implementation.

(The correct solution is for the compiler not to allow
the definition of any type
Do you mean "declaration"?
that is so large that sizeof cannot yield the correct
result as required).


My compiler does allow such declarations.

--
pete
Nov 15 '05 #17
Confused User wrote:
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, size_t n).

So, is size_t the native size of the machine or used to describe the
actual size of something (like the len of a string copy).

If it is named because it designates the size of something, then
could I still have more than 65535 bytes of something. If so why is
that called size_t.

I understand that it is just an int, but I don't understand the name.
I can have a size that is larger than an int. Perhaps I could store
the size of something in long? Wow?!?!?!

What the heck are the origins for the name?

Elvis


Wasn't it so ther would be a common size among different compilers, or
something of the sort?

--
Stan

Posted Via Usenet.com Premium Usenet Newsgroup Services
----------------------------------------------------------
** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
----------------------------------------------------------
http://www.usenet.com
Nov 15 '05 #18
Stan R. wrote:
Confused User wrote:
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, size_t
n). So, is size_t the native size of the machine or used to describe
the
actual size of something (like the len of a string copy).

If it is named because it designates the size of something, then
could I still have more than 65535 bytes of something. If so why is
that called size_t.

I understand that it is just an int, but I don't understand the name.
I can have a size that is larger than an int. Perhaps I could store
the size of something in long? Wow?!?!?!

What the heck are the origins for the name?

Elvis


Wasn't it so ther would be a common size among different compilers, or
something of the sort?

--
Stan


--
Stan

Posted Via Usenet.com Premium Usenet Newsgroup Services
----------------------------------------------------------
** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
----------------------------------------------------------
http://www.usenet.com
Nov 15 '05 #19
Robert Gamble wrote:
Clark S. Cox III wrote:
On 2005-06-23 08:21:32 -0400, "S.Tobias"
<si***@FamOuS.BedBuG.pAlS.INVALID> said:
Gordon Burditt <go***********@burditt.org> wrote:

> If it is named because it designates the size of something, then
> could I still have more than 65535 bytes of something.
> Really? How? malloc() takes a size_t as an argument, so you
> can't
Robert Gamble


--
Stan

Posted Via Usenet.com Premium Usenet Newsgroup Services
----------------------------------------------------------
** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
----------------------------------------------------------
http://www.usenet.com
Nov 15 '05 #20
pete <pf*****@mindspring.com> wrote:
S.Tobias wrote:

pete <pf*****@mindspring.com> wrote:
N869
6.5.3.4 The sizeof operator
[#2] The sizeof operator yields the size (in bytes) of its
operand, which may be an expression or the parenthesized
name of a type
If the size cannot be taken, then how can sizeof do
what it's supposed to do?


So what should a compiler do? Should it reject the code which
contains a declaration of type that is too large, or is it UB
applying `sizeof' to such type?

My compiler accepts the oversized declaration,
I just can't use it anywhere. When I uncomment array_5, i get:
new.c(11) : error C2089: 'structure' : 'struct' too large /* BEGIN new.c */ #include <stdio.h> struct structure {
char array_0[(size_t)-1 / 5];
char array_1[(size_t)-1 / 5];
char array_2[(size_t)-1 / 5];
char array_3[(size_t)-1 / 5];
char array_4[(size_t)-1 / 5];
/* char array_5[(size_t)-1 / 5];*/
}; int main(void)
{
printf("sizeof(array) is %lu\n",
(long unsigned)sizeof(struct structure));
return 0;
} /* END new.c */


AFAICT this program is strictly conforming (I believe there're no limits
on size of types), and there is no reason to reject it, not at least
at the point of struct declaration. I think it's a defect in the Standard.
There's an interesting answer from Robert Gamble, pointing to DR266.
I think the Committee's response misses the point, but at least
it indicates there's no constraint violation there (diagnostics
is not required).

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 15 '05 #21
On Thu, 23 Jun 2005 23:36:26 +0100, Christian Bau wrote:
In article <3i************@individual.net>,
"S.Tobias" <si***@FamOuS.BedBuG.pAlS.INVALID> wrote:
pete <pf*****@mindspring.com> wrote:
> S.Tobias wrote:
>
> > I don't understand. Where exactly is it written that `size_t' must
> > be able to cover sizes of all types? All I can find is that `size_t'
> > is the type returned by `sizeof' operator. Does it mean that
> > implementations must forbid types whose size cannot be taken?
> N869
> 6.5.3.4 The sizeof operator
> [#2] The sizeof operator yields the size (in bytes) of its
> operand, which may be an expression or the parenthesized
> name of a type

> If the size cannot be taken, then how can sizeof do
> what it's supposed to do?

It can't which means that the compiler should not successfully translate
the program, which is fine.
So what should a compiler do? Should it reject the code which
contains a declaration of type that is too large, or is it UB
applying `sizeof' to such type?


It takes the 3rd option: "I accept your code but I can't translate it".
It doesn't say anywhere that it is undefined behavior.
Well undefined behaviour can occur as a lack of definition of behaviour,
but I don't think that's a valid argument here.
6.5.3.4 clearly
says what the compiler has to do. If the compiler cannot do what it has
to do, then it should better tell the user.
If it cannot generate code that conforms to the standard's specificaton
then it must not generate code.
(The correct solution is for the compiler not to allow the definition of
any type that is so large that sizeof cannot yield the correct result as
required).


An important principle here is that a conforming implementation is only
required to be able to successfully translate and execute ONE program as
specified in 5.2.4.1. That makes some sense if you consider that a
strictly conforming program can be arbitrarily large and use an
arbitrarily large amount of static and automatic storage, even if
individual objects are all small. So if you required a conforming
implementation to successfully translate and execute all strictly
conforming programs, there could be no conforming implementations in the
real world.

Lawrence

Nov 15 '05 #22
Lawrence Kirby wrote:

On Thu, 23 Jun 2005 23:36:26 +0100, Christian Bau wrote:
In article <3i************@individual.net>,
"S.Tobias" <si***@FamOuS.BedBuG.pAlS.INVALID> wrote:
pete <pf*****@mindspring.com> wrote:
> S.Tobias wrote:
>
> > I don't understand.
> > Where exactly is it written that `size_t' must
> > be able to cover sizes of all types?
> > All I can find is that `size_t'
> > is the type returned by `sizeof' operator. Does it mean that
> > implementations must forbid types whose size cannot be taken?

> N869
> 6.5.3.4 The sizeof operator
> [#2] The sizeof operator yields
> the size (in bytes) of its
> operand, which may be an expression or the
> parenthesized
> name of a type

> If the size cannot be taken, then how can sizeof do
> what it's supposed to do?
It can't which means that the compiler
should not successfully translate
the program, which is fine.
So what should a compiler do? Should it reject the code which
contains a declaration of type that is too large, or is it UB
applying `sizeof' to such type?
It takes the 3rd option:
"I accept your code but I can't translate it".
What does "accept" mean?

I don't know that "accept" means
"be able to successfully translate and execute",
but I can't think of what else it could mean.
It doesn't say anywhere that it is undefined behavior.


Well undefined behaviour can occur as
a lack of definition of behaviour,
but I don't think that's a valid argument here.
6.5.3.4 clearly
says what the compiler has to do.
If the compiler cannot do what it has
to do, then it should better tell the user.


If it cannot generate code that conforms to the standard's
specificaton then it must not generate code.


Beyond generating code,
I can't apply meaning to what sizeof is supposed to do.
When the operand is a type with (1 + (size_t)-1) bytes.
what should sizeof return?
I can't answer that question in English.
It's not just a matter of generating code.
(The correct solution is for the compiler
not to allow the definition of
any type that is so large that sizeof
cannot yield the correct result as
required).


An important principle here is that a conforming implementation
is only required to be able to successfully translate
and execute ONE program as specified in 5.2.4.1.
That makes some sense if you consider that a
strictly conforming program can be arbitrarily large and use an
arbitrarily large amount of static and automatic storage, even if
individual objects are all small.


If a program defines two objects
or an object with more than 65535 bytes,
then it is beyond what 5.2.4.1 says
an implementation shall be able to translate and execute.
So if you required a conforming
implementation to successfully translate and execute all strictly
conforming programs,
there could be no conforming implementations in the real world.


I think the "one" reference is saying that
if something can translate and execute any strictly conforming program
then it's a conforming implementation,
and that if it can't, it isn't.

--
pete
Nov 15 '05 #23
"Stan R." <st*********@bremove.lz.hmrprint.com> writes:
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, size_t n).


Wasn't it so ther would be a common size among different compilers, or
something of the sort?


No. It is so each compiler can choose its own type to represent
a size.
--
Ben Pfaff
email: bl*@cs.stanford.edu
web: http://benpfaff.org
Nov 15 '05 #24
pete <pf*****@mindspring.com> wrote:

The question is
"Should it reject the code which contains a declaration
of type that is too large, or is it UB applying `sizeof' to such type?"


There was a great deal of discussion about that when the committee
considered DR 266. Whilst many people thought that the compiler was
obliged to reject such code, others thought that it was just undefined
behavior. The final decision (as reflected in the DR response) is that
such code is not strictly conforming, the compiler is allowed to reject
it, the compiler is also allowed to accept it (no diagnostic is
required) but applying sizeof results in undefined behavior (with a
compile-time diagnostic desirable but not required).

-Larry Jones

I've got more brains than I know what to do with. -- Calvin
Nov 15 '05 #25
la************@ugs.com wrote:

pete <pf*****@mindspring.com> wrote:

The question is
"Should it reject the code which contains a declaration
of type that is too large,
or is it UB applying `sizeof' to such type?"


There was a great deal of discussion about that when the committee
considered DR 266. Whilst many people thought that the compiler was
obliged to reject such code,
others thought that it was just undefined behavior.
The final decision (as reflected in the DR response) is that
such code is not strictly conforming,
the compiler is allowed to reject it,
the compiler is also allowed to accept it (no diagnostic is
required) but applying sizeof results in undefined behavior (with a
compile-time diagnostic desirable but not required).


Thank you.

--
pete
Nov 15 '05 #26
On Fri, 24 Jun 2005 11:23:54 +0000, pete wrote:
Lawrence Kirby wrote:

On Thu, 23 Jun 2005 23:36:26 +0100, Christian Bau wrote:
> In article <3i************@individual.net>,
> "S.Tobias" <si***@FamOuS.BedBuG.pAlS.INVALID> wrote:
>
>> pete <pf*****@mindspring.com> wrote:
>> > S.Tobias wrote:
>> >
>> > > I don't understand.
>> > > Where exactly is it written that `size_t' must
>> > > be able to cover sizes of all types?
>> > > All I can find is that `size_t'
>> > > is the type returned by `sizeof' operator. Does it mean that
>> > > implementations must forbid types whose size cannot be taken?
>>
>> > N869
>> > 6.5.3.4 The sizeof operator
>> > [#2] The sizeof operator yields
>> > the size (in bytes) of its
>> > operand, which may be an expression or the
>> > parenthesized
>> > name of a type
>>
>> > If the size cannot be taken, then how can sizeof do
>> > what it's supposed to do?
It can't which means that the compiler
should not successfully translate
the program, which is fine.
>> So what should a compiler do? Should it reject the code which
>> contains a declaration of type that is too large, or is it UB
>> applying `sizeof' to such type?


It takes the 3rd option:
"I accept your code but I can't translate it".


What does "accept" mean?

I don't know that "accept" means
"be able to successfully translate and execute",
but I can't think of what else it could mean.
> It doesn't say anywhere that it is undefined behavior.


Well undefined behaviour can occur as
a lack of definition of behaviour,
but I don't think that's a valid argument here.
> 6.5.3.4 clearly
> says what the compiler has to do.
> If the compiler cannot do what it has
> to do, then it should better tell the user.


If it cannot generate code that conforms to the standard's
specificaton then it must not generate code.


Beyond generating code,
I can't apply meaning to what sizeof is supposed to do.


sizeof returns the size of the type of its operand. If it cannot
successfully evaluate to a value that meets the requirements of the
standard then it mut nut successfully evaluate.

Actually my statement the the compiler must not generate code is too
strong, the compiler can generate code but the code must not complete
such a sizeof operation successfully.
When the operand is a type with (1 + (size_t)-1) bytes.
what should sizeof return?
That's the point, it cannot produce a result without violating the
standard so it must not produce a result.
I can't answer that question in English. It's not just a matter of
generating code.


It is a matter of implementing the semantics specified by the standard.
It is clear that in this case those semantic cannot be implemented, well
before generating code is an issue.

There is a defect in the standard in as much as it should state that the
size of a declared object shall not exceed SIZE_MAX. That would allow
undefined behavour. However as things stand there is no opportunity for
undefined behaviour because the behaviour of sizeof is clearly defined. It
just happens to be unimplementable in this case which is a clear defect.
> (The correct solution is for the compiler not to allow the definition
> of
> any type that is so large that sizeof cannot yield the correct result
> as
> required).


An important principle here is that a conforming implementation is only
required to be able to successfully translate and execute ONE program
as specified in 5.2.4.1. That makes some sense if you consider that a
strictly conforming program can be arbitrarily large and use an
arbitrarily large amount of static and automatic storage, even if
individual objects are all small.


If a program defines two objects
or an object with more than 65535 bytes, then it is beyond what 5.2.4.1
says
an implementation shall be able to translate and execute.


It is certainly more than is required for the one program that the
implementation must be able to translate and execute successfully. However
that doesn't stop it being a strictly conforming program.
So if you required a conforming
implementation to successfully translate and execute all strictly
conforming programs,
there could be no conforming implementations in the real world.


I think the "one" reference is saying that if something can translate
and execute any strictly conforming program then it's a conforming
implementation, and that if it can't, it isn't.


The text is pretty clear:

"The implementation shall be able to translate and execute at least one
program that contains at least one instance of every one of the following
limits."

It is a conformance requirement on the implementation. There must be at
least one program that the implementation can translate and execute and
that program must contain at least once instance of each of the specified
limits. There is nothing in the standard that requires that an
implementation be able to successfully translate and execute any other
program.

It is easy to construct strictly conforming programs for a compiler that
it can't translate and execute successfully, so the standard cannot
require an implementation to translate and execute every strictly
conforming program, if it is to be useful in the real world.

Lawrence


Nov 15 '05 #27
Lawrence Kirby wrote:

On Fri, 24 Jun 2005 11:23:54 +0000, pete wrote:

I think the "one" reference
is saying that if something can translate
and execute any strictly conforming program
then it's a conforming implementation,
and that if it can't, it isn't.


The text is pretty clear:

"The implementation shall be able to
translate and execute at least one
program that contains at least one
instance of every one of the following limits."

It is a conformance requirement on the implementation.
There must be at
least one program that the implementation
can translate and execute and
that program must contain at least once instance
of each of the specified
limits. There is nothing in the standard that requires that an
implementation be able to successfully translate and execute any other
program.

It is easy to construct strictly conforming programs
for a compiler that
it can't translate and execute successfully, so the standard cannot
require an implementation to translate and execute every strictly
conforming program, if it is to be useful in the real world.


I think your interpretation beats mine for uselessness.

An implementation that can only translate
and execute one specific strictly conforming program,
and no others,:
int main(void) {return 0;}
for example, is pretty useless.

--
pete
Nov 15 '05 #28
pete wrote:

Lawrence Kirby wrote:

On Fri, 24 Jun 2005 11:23:54 +0000, pete wrote:

I think the "one" reference
is saying that if something can translate
and execute any strictly conforming program
then it's a conforming implementation,
and that if it can't, it isn't.


The text is pretty clear:

"The implementation shall be able to
translate and execute at least one
program that contains at least one
instance of every one of the following limits."

It is a conformance requirement on the implementation.
There must be at
least one program that the implementation
can translate and execute and
that program must contain at least once instance
of each of the specified
limits. There is nothing in the standard that requires that an
implementation be able to successfully translate
and execute any other program.

It is easy to construct strictly conforming programs
for a compiler that
it can't translate and execute successfully, so the standard cannot
require an implementation to translate and execute every strictly
conforming program, if it is to be useful in the real world.


I think your interpretation beats mine for uselessness.

An implementation that can only translate
and execute one specific strictly conforming program,
and no others,:
int main(void) {return 0;}
for example, is pretty useless.


Well, that example is wrong because it doesn't contain one instance
of each of those specified limits.
But, a requirement that a conforming implementation
only need to be able to translate and execute
one specific program, is pretty useless.

--
pete
Nov 15 '05 #29
Lawrence Kirby wrote:
.... snip ...
sizeof returns the size of the type of its operand. If it cannot
successfully evaluate to a value that meets the requirements of
the standard then it mut nut successfully evaluate.

Actually my statement the the compiler must not generate code is
too strong, the compiler can generate code but the code must not
complete such a sizeof operation successfully.


sizeof cannot possibly fail. It doesn't really exist as an
operator. The compiler has to keep track of the storage needs of
components in some manner or other in order to assign that
storage. sizeof is simply a means of transmitting those numbers
for use in a program. What is unknown a-priori is the range of
those values, thus a size_t type is needed.

--
"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare

Nov 15 '05 #30
In article <42***********@mindspring.com>
pete <pf*****@mindspring.com> wrote:
[My, i.e., Pete's earlier] example is wrong because it doesn't
contain one instance of each of those specified limits.
But, a requirement that a conforming implementation
only need to be able to translate and execute
one specific program, is pretty useless.


Indeed. However, the all-or-nothing nature of the Standard would
otherwise require a conforming implementation to be able to translate
and execute *every* program that contains one instance of each of
those limits, and/or every program that does not exceed any or all
of those limits.

I think this would actually be useful in a theoretical sense, but
you can probably imagine that it would be quite untestable in a
practical sense. :-)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 15 '05 #31
Chris Torek wrote:

In article <42***********@mindspring.com>
pete <pf*****@mindspring.com> wrote:
[My, i.e., Pete's earlier] example is wrong because it doesn't
contain one instance of each of those specified limits.
But, a requirement that a conforming implementation
only need to be able to translate and execute
one specific program, is pretty useless.
Indeed. However, the all-or-nothing nature of the Standard would
otherwise require a conforming implementation to be able to translate
and execute *every* program that contains one instance of each of
those limits, and/or every program that does not exceed any or all
of those limits.


So then, what do you think "accept" means, as in:
"A conforming hosted implementation
shall accept any strictly conforming program."
I think this would actually be useful in a theoretical sense, but
you can probably imagine that it would be quite untestable in a
practical sense. :-)


--
pete
Nov 15 '05 #32
>Chris Torek wrote:
Indeed. However, the all-or-nothing nature of the Standard would
otherwise require a conforming implementation to be able to translate
and execute *every* program that contains one instance of each of
those limits, and/or every program that does not exceed any or all
of those limits.

In article <42***********@mindspring.com>,
pete <pf*****@mindspring.com> wrote:So then, what do you think "accept" means, as in:
"A conforming hosted implementation
shall accept any strictly conforming program."


I think this means "accept" in the computer-grammar and parsing
sense, i.e., agree that the syntax is correct.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 15 '05 #33
Chris Torek wrote:
Chris Torek wrote:
Indeed. However, the all-or-nothing nature of the Standard would
otherwise require a conforming implementation to be able to translate
and execute *every* program that contains one instance of each of
those limits, and/or every program that does not exceed any or all
of those limits.


In article <42***********@mindspring.com>,
pete <pf*****@mindspring.com> wrote:
So then, what do you think "accept" means, as in:
"A conforming hosted implementation
shall accept any strictly conforming program."


I think this means "accept" in the computer-grammar and parsing
sense, i.e., agree that the syntax is correct.


Does that mean that it would have to
be able to compile but not necessarily link?
I can't think of any other way to verify that
the implementation likes the syntax, except by compiling.

--
pete
Nov 15 '05 #34
On Sat, 25 Jun 2005 15:41:39 +0000, CBFalconer wrote:
Lawrence Kirby wrote:
... snip ...

sizeof returns the size of the type of its operand. If it cannot
successfully evaluate to a value that meets the requirements of
the standard then it mut nut successfully evaluate.

Actually my statement the the compiler must not generate code is
too strong, the compiler can generate code but the code must not
complete such a sizeof operation successfully.


sizeof cannot possibly fail.


It cannot succeed when the value it is required to produce (the size of
the object/type) is outside the range of the values it is allowed to
generate (0 to SIZE_MAX).
It doesn't really exist as an
operator.
The C standard defines it as an operator. That is what it is.
The compiler has to keep track of the storage needs of
components in some manner or other in order to assign that
storage. sizeof is simply a means of transmitting those numbers
for use in a program. What is unknown a-priori is the range of
those values, thus a size_t type is needed.


Yes, the question is what happens when size_t cannot represent the
required value.

Lawrence
Nov 15 '05 #35
On Sun, 26 Jun 2005 00:54:40 +0000, Chris Torek wrote:
Chris Torek wrote:
Indeed. However, the all-or-nothing nature of the Standard would
otherwise require a conforming implementation to be able to translate
and execute *every* program that contains one instance of each of
those limits, and/or every program that does not exceed any or all
of those limits.


In article <42***********@mindspring.com>,
pete <pf*****@mindspring.com> wrote:
So then, what do you think "accept" means, as in:
"A conforming hosted implementation
shall accept any strictly conforming program."


I think this means "accept" in the computer-grammar and parsing
sense, i.e., agree that the syntax is correct.


Even that is too strong to be practical; strictly conforming programs can
be arbitrarily large. I doubt if, for example, any real-world preprocessor
can deal with an arbitrarily large sequence of #defines, or at least large
enough to cover every valid user namespace identifier.

"Accept" here IMO means "not reject" so a "I accept your program as
as possibly correct but I can't translate it" is a valid accept response
EXCEPT for the one specified program. As a diagnostic it also covers the
case where the program has a syntax error or constraint violation.

Lawrence

Nov 15 '05 #36
Lawrence Kirby wrote:
On Sat, 25 Jun 2005 15:41:39 +0000, CBFalconer wrote:
.... snip ...
The C standard defines it as an operator. That is what it is.
The compiler has to keep track of the storage needs of
components in some manner or other in order to assign that
storage. sizeof is simply a means of transmitting those numbers
for use in a program. What is unknown a-priori is the range of
those values, thus a size_t type is needed.


Yes, the question is what happens when size_t cannot represent the
required value.


That's the point. The object can't exist when the compiler can't
keep track of its storage needs. Therefore the question is moot.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 15 '05 #37
On Mon, 27 Jun 2005 00:25:47 +0000, CBFalconer wrote:
Lawrence Kirby wrote:
On Sat, 25 Jun 2005 15:41:39 +0000, CBFalconer wrote:

... snip ...

The C standard defines it as an operator. That is what it is.
The compiler has to keep track of the storage needs of
components in some manner or other in order to assign that
storage. sizeof is simply a means of transmitting those numbers
for use in a program. What is unknown a-priori is the range of
those values, thus a size_t type is needed.


Yes, the question is what happens when size_t cannot represent the
required value.


That's the point. The object can't exist when the compiler can't
keep track of its storage needs. Therefore the question is moot.


There's nothing to stop the compiler keeping track of its storage needs
using something other than size_t internally. The problem occurs when
the program explicitly asks about its size. The compiler is then
constrained to produce a value representable as a size_t.

I agree that this is a wrinkle in the language and the standard should
explicitly disallow declared objects of more than SIZE_MAX bytes, either
as undefined behaviour or a constraint. There is room for debate over
which is appropriate.

Lawrence
Nov 15 '05 #38
On Sat, 25 Jun 2005 13:05:38 +0000, pete wrote:
Lawrence Kirby wrote:

On Fri, 24 Jun 2005 11:23:54 +0000, pete wrote:
> I think the "one" reference
> is saying that if something can translate
> and execute any strictly conforming program
> then it's a conforming implementation,
> and that if it can't, it isn't.


The text is pretty clear:

"The implementation shall be able to
translate and execute at least one
program that contains at least one
instance of every one of the following limits."

It is a conformance requirement on the implementation.
There must be at
least one program that the implementation
can translate and execute and
that program must contain at least once instance
of each of the specified
limits. There is nothing in the standard that requires that an
implementation be able to successfully translate and execute any other
program.

It is easy to construct strictly conforming programs
for a compiler that
it can't translate and execute successfully, so the standard cannot
require an implementation to translate and execute every strictly
conforming program, if it is to be useful in the real world.


I think your interpretation beats mine for uselessness.


I have to disagree on that. :-)

Your interpretation means that there can be no real-world conforming
implementations, which is about as useless as you can get. It means that
nothing can claim conformance and if your compiler doesn't claim
conformance you have no comeback on standards grounds when the compiler
generates code that produces wrong results.

My interpretation means that you can create trivial conforming
implementations. For example you can write a program that simply tests
whether the source code against its designated "one" program and writes a
prebuilt executable for that code. For any other code it just says "sorry
I couldn't compile that". Now that may sound pretty useless but it turns
out to be not too bad because:

1. Conforming implementations are possible

2. An implementation that claims conformance is bound by the rules of the
standard. If if produces wrong output you have a sound basis for
complaint.

3. In practice a "trivial" implementation wouldn't last very long.
Compiler writers have a vested interest in making implementations
that are useful. It is a quality of implementation issue rather than
a correctness (conformance) issue. The fact is that real-world
compilers DO attempt to implement the features of the language and
when they do translate code the rules mean that they have to do it
right to conform.

So it turns out that this isn't a bad approach after all.
An implementation that can only translate
and execute one specific strictly conforming program,
and no others,:
int main(void) {return 0;}
for example, is pretty useless.


So don't buy it. At least it won't corrupt your valuable database by
generating WRONG code from your application source.

Note that this isn't valid as an example of a "one" designated program
because it doesn't contain at least one instance of all of the
implementation limits. However such programs can be equally useless.

Lawrence

Nov 15 '05 #39
Lawrence Kirby wrote:
I think your interpretation beats mine for uselessness.


I have to disagree on that. :-)


OK.
Well you and Chris Torek seem to be on the same page,
so I'll just think about it for a while.

--
pete
Nov 15 '05 #40
On Mon, 27 Jun 2005 09:12:45 -0500, pete wrote
(in article <42***********@mindspring.com>):
Lawrence Kirby wrote:
I think your interpretation beats mine for uselessness.


I have to disagree on that. :-)


OK.
Well you and Chris Torek seem to be on the same page,
so I'll just think about it for a while.


The force is strong in this one Obi-Wan.

--
Randy Howard
2reply remove FOOBAR

Nov 15 '05 #41

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.