Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > sizeof observation

Reply
Thread Tools

sizeof observation

 
 
nzanella@cs.mun.ca
Guest
Posts: n/a
 
      08-02-2005
Hello,

I just thought I would share the following observation with the rest
of the group. The sizeof operator seems to act differently according
to whether the number of elements in the array is known. Hence when
passing arrays to functions the number of elements in the array must
always be passed as an argument. If STL is available then people can
just use vectors of course. Anyways, I guess this stuff is pretty
standard. Well, have a nice day,

Neil

#include <cstdio>

void hello(const char *foo[]) {
printf("%u\n", sizeof(foo)/sizeof(char));
}

int main() {
const char *foo[8];
const char *bar[] = { "aa", "bb" };
printf("%u\n", sizeof(foo)/sizeof(char));
//BTW sizeof(char) is always going to be one
printf("%u\n", sizeof(bar)/sizeof(char));
//BTW sizeof(char) is always going to be one
hello(foo);
}

Output:

$ ./a.out
32
8
4

 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      08-02-2005
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> I just thought I would share the following observation with the rest
> of the group. The sizeof operator seems to act differently according
> to whether the number of elements in the array is known.


No, it "acts" differently when you supply different types to it.

> Hence when
> passing arrays to functions the number of elements in the array must
> always be passed as an argument. If STL is available then people can
> just use vectors of course. Anyways, I guess this stuff is pretty
> standard.


Yes. And pretty basic too.

> Well, have a nice day,


Thanks. Same to you.

>
> Neil
>
> #include <cstdio>
>
> void hello(const char *foo[]) {


In this function 'foo' is not an array. It's a pointer. The [] notation
is a left-over from C days (like the "native" arrays, of course), and it
simply declares the argument as a pointer. If you want to pass an array,
you can, by reference. You should do

void hello(const char *(&foo)[8])

In that case, 'foo' is a reference to an array of eight pointers to const
char. And, just like with any other reference, if you use the 'sizeof'
operator on it, you will get the size of the object it refers to.

> printf("%u\n", sizeof(foo)/sizeof(char));


BTW, 'sizeof(char)' is _always_ 1. Dividing by it makes no sense. You
probably wanted to divide by 'sizeof(const char*)' which would give you
the _number_ of elements in the array.

> }
>
> int main() {
> const char *foo[8];
> const char *bar[] = { "aa", "bb" };
> printf("%u\n", sizeof(foo)/sizeof(char));
> //BTW sizeof(char) is always going to be one


Yes, by definition of 'sizeof'. There is no sense in dividing by 1, is
there?

> printf("%u\n", sizeof(bar)/sizeof(char));
> //BTW sizeof(char) is always going to be one
> hello(foo);
> }
>
> Output:
>
> $ ./a.out
> 32
> 8
> 4



V
 
Reply With Quote
 
 
 
 
Alipha
Guest
Posts: n/a
 
      08-02-2005

(E-Mail Removed) wrote:
> Hello,
>
> I just thought I would share the following observation with the rest
> of the group. The sizeof operator seems to act differently according
> to whether the number of elements in the array is known. Hence when
> passing arrays to functions the number of elements in the array must
> always be passed as an argument. If STL is available then people can
> just use vectors of course. Anyways, I guess this stuff is pretty
> standard. Well, have a nice day,
>
> Neil
>
> #include <cstdio>
>
> void hello(const char *foo[]) {
> printf("%u\n", sizeof(foo)/sizeof(char));
> }
>
> int main() {
> const char *foo[8];
> const char *bar[] = { "aa", "bb" };
> printf("%u\n", sizeof(foo)/sizeof(char));
> //BTW sizeof(char) is always going to be one
> printf("%u\n", sizeof(bar)/sizeof(char));
> //BTW sizeof(char) is always going to be one
> hello(foo);
> }
>
> Output:
>
> $ ./a.out
> 32
> 8
> 4


Instead of the sizeof idiom for determining the number of elements in
an array, you might want to consider using this function instead:

template<typename T, std::size_t N>
inline std::size_t countof( T (&)[N] ) { return N; }

this function won't compile if you pass a pointer to it (calling
countof(foo) inside hello will error) and you can't make mistakes such
as dividing by sizeof(char) instead of by sizeof(const char*) like you
should be doing.

btw, if you're including <cstdio> (why not <iostream>?) it is
std:rintf, etc. all standard identifiers are in the std namespace.

 
Reply With Quote
 
wkaras@yahoo.com
Guest
Posts: n/a
 
      08-02-2005
Victor Bazarov wrote:
....
>
> > printf("%u\n", sizeof(foo)/sizeof(char));

>
> BTW, 'sizeof(char)' is _always_ 1. Dividing by it makes no sense. You
> probably wanted to divide by 'sizeof(const char*)' which would give you
> the _number_ of elements in the array.

....

This may not be true if you're trying to write code that is valid as
either C or C++ code. C originally defined sizeof to return the
number of bytes of storage needed, and a byte and a char were not
necessarily the same thing. Architectures with instructions that
operated on units of memory whose size wasn't a power of two
disappeared from widespread use around 1980, and C++ assumed the dead
would not rise again.

 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      08-02-2005
(E-Mail Removed) wrote:
> Victor Bazarov wrote:
> ...
>
>>> printf("%u\n", sizeof(foo)/sizeof(char));

>>
>>BTW, 'sizeof(char)' is _always_ 1. Dividing by it makes no sense. You
>>probably wanted to divide by 'sizeof(const char*)' which would give you
>>the _number_ of elements in the array.

>
> ...
>
> This may not be true if you're trying to write code that is valid as
> either C or C++ code.


That's nonsense. It's true for both C and C++.

> C originally defined sizeof to return the
> number of bytes of storage needed, and a byte and a char were not
> necessarily the same thing.


Care to give a quote from some document which would define that?

> Architectures with instructions that
> operated on units of memory whose size wasn't a power of two
> disappeared from widespread use around 1980, and C++ assumed the dead
> would not rise again.
>


C defines 'byte' to be "addressable unit of data storage large enough to
hold any member of the basic character set of the execution environment".
And also in 6.5.3.4, it says "When applied to an operand that has type
char, unsigned char, or signed char, (or a qualified version thereof) the
result is 1." Where you see a conflict with some [unusual or now dead]
architectures, I am not sure.

V
 
Reply With Quote
 
wkaras@yahoo.com
Guest
Posts: n/a
 
      08-02-2005
Victor Bazarov wrote:
> (E-Mail Removed) wrote:
> > Victor Bazarov wrote:
> > ...
> >
> >>> printf("%u\n", sizeof(foo)/sizeof(char));
> >>
> >>BTW, 'sizeof(char)' is _always_ 1. Dividing by it makes no sense. You
> >>probably wanted to divide by 'sizeof(const char*)' which would give you
> >>the _number_ of elements in the array.

> >
> > ...
> >
> > This may not be true if you're trying to write code that is valid as
> > either C or C++ code.

>
> That's nonsense. It's true for both C and C++.


I'll take your word for it that sizeof(char) == 1 has made it
into the C Standard now as well. But I still see alot of
"#ifdef ANSI_C" as I'm browsing through C code. C is all
about anachronism these days, which could make for a big lag
between compiler versions in wide usage and the current
C Standard.

> > C originally defined sizeof to return the
> > number of bytes of storage needed, and a byte and a char were not
> > necessarily the same thing.

>
> Care to give a quote from some document which would define that?


Nah, too lazy to try.

> > Architectures with instructions that
> > operated on units of memory whose size wasn't a power of two
> > disappeared from widespread use around 1980, and C++ assumed the dead
> > would not rise again.
> >

>
> C defines 'byte' to be "addressable unit of data storage large enough to
> hold any member of the basic character set of the execution environment".
> And also in 6.5.3.4, it says "When applied to an operand that has type
> char, unsigned char, or signed char, (or a qualified version thereof) the
> result is 1." Where you see a conflict with some [unusual or now dead]
> architectures, I am not sure.


The DEC/PDP 10 had word size of 36 bits. The size of a character could
be set (by loading a special register) to 6, 7, 8 or 9 bits. I never
saw a C implementation for the DEC 10. If char was defined to be
8 bits, then it would probably make sense to define a byte to be 4 bits
rather than 8 (unless sizeof was redefined to return a float).

 
Reply With Quote
 
Default User
Guest
Posts: n/a
 
      08-02-2005
(E-Mail Removed) wrote:

> Victor Bazarov wrote:


> > That's nonsense. It's true for both C and C++.

>
> I'll take your word for it that sizeof(char) == 1 has made it
> into the C Standard now as well.


If made it into there years before C++ even had a standard.

> But I still see alot of
> "#ifdef ANSI_C" as I'm browsing through C code. C is all
> about anachronism these days, which could make for a big lag
> between compiler versions in wide usage and the current
> C Standard.


What nonsense is this? There's still some old pre-standard C code
around, yeah, but the same is true (probably more so) for C++. C has
been standardized several years longer.

> The DEC/PDP 10 had word size of 36 bits. The size of a character
> could be set (by loading a special register) to 6, 7, 8 or 9 bits. I
> never saw a C implementation for the DEC 10. If char was defined to
> be 8 bits, then it would probably make sense to define a byte to be 4
> bits rather than 8 (unless sizeof was redefined to return a float).


There's no requirement for char to be eight bits, in either language.
It must be at least eight.



Brian
 
Reply With Quote
 
wkaras@yahoo.com
Guest
Posts: n/a
 
      08-03-2005
Default User wrote:
> (E-Mail Removed) wrote:
>
> > Victor Bazarov wrote:

>
> > > That's nonsense. It's true for both C and C++.

> >
> > I'll take your word for it that sizeof(char) == 1 has made it
> > into the C Standard now as well.

>
> If made it into there years before C++ even had a standard.


Looks like you're right about that, it was in the first ANSI
C Standard. Anyone still got a first ed. of K&R? Be interested
to hear what it says about this issue.

> > But I still see alot of
> > "#ifdef ANSI_C" as I'm browsing through C code. C is all
> > about anachronism these days, which could make for a big lag
> > between compiler versions in wide usage and the current
> > C Standard.

>
> What nonsense is this? There's still some old pre-standard C code
> around, yeah, but the same is true (probably more so) for C++. C has
> been standardized several years longer.


There's a high probability that no C/C++ compiler in use now (or that
was ever used) has sizeof(char) != 1 . But in general, for both C
and C++, if you really want to maximize the portability of your
source code (even for those nonsensical and morally inferior people
who use a compiler that isn't 100% Standard compliant), it's more
complex than just coding to the standard.

> > The DEC/PDP 10 had word size of 36 bits. The size of a character
> > could be set (by loading a special register) to 6, 7, 8 or 9 bits. I
> > never saw a C implementation for the DEC 10. If char was defined to
> > be 8 bits, then it would probably make sense to define a byte to be 4
> > bits rather than 8 (unless sizeof was redefined to return a float).

>
> There's no requirement for char to be eight bits, in either language.
> It must be at least eight.


Yeah just make it 9 bits and waste a bit. I guess I just need to get
over the traumas of having learned to program on a machine that used
magnetic core memory.

 
Reply With Quote
 
 
 
Reply

Thread Tools

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

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
sizeof(EmptyStruct) in C and C++ (was: Base {}; sizeof(Base) == 1?) Alex Vinokur C Programming 7 08-14-2006 04:57 PM
sizeof( int ) != sizeof( void * ) blufox C Programming 2 05-22-2006 03:25 PM
#define ARR_SIZE sizeof(arr)/sizeof(arr[0]) Vinu C Programming 13 05-12-2005 06:00 PM
sizeof(enum) == sizeof(int) ??? Derek C++ 7 10-14-2004 05:11 PM
sizeof(str) or sizeof(str) - 1 ? Trevor C Programming 9 04-10-2004 05:07 PM



Advertisments