sizeof observation

N

nzanella

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
 
V

Victor Bazarov

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
 
A

Alipha

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::printf, etc. all standard identifiers are in the std namespace.
 
W

wkaras

Victor Bazarov wrote:
....
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.
 
V

Victor Bazarov

Victor Bazarov wrote:
...


...

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
 
W

wkaras

Victor said:
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.
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).
 
D

Default User

Victor Bazarov wrote:

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
 
W

wkaras

Default said:
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.
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.
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.
 

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

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,177
Latest member
OrderGlucea
Top