sizeof() , different results for same thing in C and C++. Why?

B

Boltar

Hi

Why - using gcc on linux - does this return 0 in C but returns 1 in C+
+? I don't get it.

#include <stdio.h>

struct foo
{
};


main()
{
printf("%d\n",sizeof(struct foo));
}



B2003
 
T

Tomás Ó hÉilidhe

Boltar said:
Why - using gcc on linux - does this return 0 in C but returns 1 in C+
+? I don't get it.

#include <stdio.h>

struct foo
{
};


main()
{
printf("%d\n",sizeof(struct foo));
}


Change:
sizeof(struct foo)
to:
(int)sizeof(struct foo)

(You shouldn't supply printf with a size_t if you're using %d)

If you get the same output then your C compiler is faulty.

In all the standards of C and C++, the value returned by sizeof will
always be non-zero.

I'd expect the size of that struct to be 1, but of course it could be 13
or 9 or 27 or 2.
 
B

Boltar

Change:
sizeof(struct foo)
to:
(int)sizeof(struct foo)

(You shouldn't supply printf with a size_t if you're using %d)

Makes no difference.
If you get the same output then your C compiler is faulty.

Its gcc 4.1.0. Perhaps it is a bug but it seems a pretty fundamental
one.
In all the standards of C and C++, the value returned by sizeof will
always be non-zero.

Why would it be non zero if theres nothing in it? Surely the whole
point of sizeof is to return the size in bytes of the members inside?
If there are no members it should be zero bytes surely? 1 makes no
sense to me.

B2003
 
J

Joe Greer

Hi

Why - using gcc on linux - does this return 0 in C but returns 1 in C+
+? I don't get it.

#include <stdio.h>

struct foo
{
};


main()
{
printf("%d\n",sizeof(struct foo));
}



B2003

Do you have RTTI turned on? That could account for it.

joe
 
C

Christian Hackl

Boltar said:
Why - using gcc on linux - does this return 0 in C but returns 1 in C+
+? I don't get it.
#include <stdio.h>
struct foo
{
};
main()
{
printf("%d\n",sizeof(struct foo));
}
[...]

Why would it be non zero if theres nothing in it? Surely the whole
point of sizeof is to return the size in bytes of the members inside?
If there are no members it should be zero bytes surely? 1 makes no
sense to me.

Someone in this group will surely give you a more sophisticated answer,
but if I recall correctly, it has to do with the fact that each object
must be individually addressable in memory, even if it's an
instantiation of an empty class or struct.
 
B

Boltar

(e-mail address removed):









Do you have RTTI turned on? That could account for it.

joe

No that I know if - just using "cc t.c" and "c++ t.c" to compile

B2003
 
E

Erik Wikström

Makes no difference.


Its gcc 4.1.0. Perhaps it is a bug but it seems a pretty fundamental
one.


Why would it be non zero if theres nothing in it? Surely the whole
point of sizeof is to return the size in bytes of the members inside?
If there are no members it should be zero bytes surely? 1 makes no
sense to me.

No, sizeof() tells you how much less free memory you will have after
creating an instance of the type. Since all objects (and ints, doubles,
etc. counts as objects in this) in both C and C++ must have an address
and no two objects are allowed to share the same address (except perhaps
when using union) an object must take at least one byte.

Another example demonstrating that the size of not the sum of the sizes
of the members is the following:

struct Test
{
char c;
int i;
};

On my machine sizeof(Test) is 8, since the integer is 4-byte aligned 3
padding bytes will be inserted between the char and the int.
 
B

Boltar

No, sizeof() tells you how much less free memory you will have after
creating an instance of the type. Since all objects (and ints, doubles,
etc. counts as objects in this) in both C and C++ must have an address
and no two objects are allowed to share the same address (except perhaps
when using union) an object must take at least one byte.

Well it seems in C this doesn't apply , since sizeof() returns zero
for an empty struct.
On my machine sizeof(Test) is 8, since the integer is 4-byte aligned 3
padding bytes will be inserted between the char and the int.

yes, but byte aligning pre-existing members isn't the same as
conjuring up a byte from nowhere.

B2003
 
B

Boltar

Someone in this group will surely give you a more sophisticated answer,
but if I recall correctly, it has to do with the fact that each object
must be individually addressable in memory, even if it's an
instantiation of an empty class or struct.

Shouldn't it be 4 (or 8) bytes then - the size of a pointer? Why 1
byte?

B2003
 
V

Victor Bazarov

Joe said:
Do you have RTTI turned on? That could account for it.

What does RTTI have to do with anything? In C++ an empty struct
has a size of 1 if instantiated stand-alone. It's done so that
individual elements of an array of those structs could be indexed
and addressed individually.

If instantiated as a base class of another object, an empty
struct does NOT contribute to the size:

stuct A {
int a;
};

struct foo {};

struct AA : foo {
int a;
};

#include <cassert>
int main() {
assert(sizeof(A) == sizeof(AA));
}

V
 
V

Victor Bazarov

Boltar said:
Shouldn't it be 4 (or 8) bytes then - the size of a pointer? Why 1
byte?

What pointer? A byte is the smallest individually addressable unit
in memory. Why waste 3 bytes (or 7)?

V
 
C

Christian Hackl

Boltar said:
Shouldn't it be 4 (or 8) bytes then - the size of a pointer? Why 1
byte?

Why should it be the same size as a pointer? The pointer variable itself
may occupy 4 or 8 bytes or whatever, but it can still *address* smaller
objects.

char c = '\0'; // sizeof(c) is 1
char *ptr = &c; // sizeof(ptr) may be 4

This is my understanding, at least. However, I'm by no means an expert,
so don't take this explanation for granted :)
 
B

Bo Persson

Boltar said:
Shouldn't it be 4 (or 8) bytes then - the size of a pointer? Why 1
byte?

The standard just says that it must be at least one byte. It could be
more, if that is better for some implementation.



Bo Persson
 
C

Christian Hackl

Bo said:
The standard just says that it must be at least one byte.

Does the standard really say that sizeof of an empty class may be more
than 1 byte? If so, why doesn't it restrict the maximum size to that of
a char, which AFAIK is guaranteed to be 1 byte?
 
E

Erik Wikström

Well it seems in C this doesn't apply , since sizeof() returns zero
for an empty struct.

I though that we agree that there was something wrong with gcc. In the C
standard section 6.2.6.1, second paragraph: "Except for bit-fields,
objects are composed of contiguous sequences of one or more bytes ...".
 
E

Erik Wikström

Does the standard really say that sizeof of an empty class may be more
than 1 byte? If so, why doesn't it restrict the maximum size to that of
a char, which AFAIK is guaranteed to be 1 byte?

What benefit is there in restricting an empty class to 1 byte? Just
guaranteeing that it is at least one is good enough for all purposes.
 
R

Rolf Magnus

Boltar said:
Well it seems in C this doesn't apply , since sizeof() returns zero
for an empty struct.

In C, empty structs are not allowed. AFAICS, the program is ill-formed.
 
M

Marc

Why - using gcc on linux - does this return 0 in C but returns 1 in C+
+? I don't get it.

#include <stdio.h>

struct foo
{
};


main()
{
printf("%d\n",sizeof(struct foo));
}

I don't now in C, but in C++ the standard requires that every complete
object size is greater than 0. Even if it's empty. Why? To avoid
overlapping of different objects. Consider this:

struct A {};

void foo ()
{
A a1;
A a2;
A* pa = &a1;
}

Now, if we use the pointer pa to access a1.. we would also be accessing a2!
This is not desirable at all.

For a better explanation:
http://code.grep.in/2005/11/c-programming-sizeof.html
 
T

Tomás Ó hÉilidhe

Boltar said:
Makes no difference.


It might not make a difference on *your* particular system, but it does
on other implementations of the C++ Standard.

Why would it be non zero if theres nothing in it?


Because the smallest addressable unit is the byte. There's nothing
smaller. Every object is made up of bytes, and the least amount of bytes
an object can have is 1.

I think the real answer you're looking for though is: Because that's just
the way it is.

Surely the whole
point of sizeof is to return the size in bytes of the members inside?


Don't forget padding.

If there are no members it should be zero bytes surely? 1 makes no
sense to me.


Again you just have to accept it, that's just the way things were chosen
to be. Pointer arithmetic is based on the size of the object... so things
would be a little more complicated if you could have zero-length objects.
Also, every object must have a unique address in memory (unless we're
talking about inheritence of course).
 
C

Christian Hackl

Erik said:
What benefit is there in restricting an empty class to 1 byte?

Hmm, well, none, I guess. I just thought it would make sense like that.
However, I am perfectly happy with the standard not putting any
restrictions on the maximum size.
 

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,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top