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

D

Default User

Boltar said:
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));
}


Seems like it's not a legal declaration in C. From the C99 draft
standard:

A structure type describes a sequentially allocated
nonempty set of member objects (and, in certain
circumstances, an incomplete array), each of which has
an optionally specified name and possibly distinct
type.


VC++ correctly flags this as an error. I tried a few options with gcc
3.3.1 but didn't get it to trigger a diagnostic. I suggest discussing
it over in comp.lang.c if you have further interest.



Brian
 
I

Ian Collins

Boltar said:
Hi

Why - using gcc on linux - does this return 0 in C but returns 1 in C+
+? I don't get it.
Did you pay attention to the compiler's warnings? Your example won't
even compile as C++.
 
D

Default User

Erik said:
On 2008-01-10 19:37, Boltar wrote:

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 ...".

It also requires structs to have a nonempty set of members.




Brian
 
J

Joe Greer

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

Sadly, I just jumped into the middle of this and spouted off the first
thing I could think of given the data that the sizeof foo was 0 in C.
Sorry for the noise.

joe
 
J

Jack Klein

Hi

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

Because you are not using gcc to compile C, but rather GNU C, which is
a different language.

#include <stdio.h>

struct foo
{
};

The structure definition above is a syntax error in C. Every
structure or union definition must define at least one member.
main()
{
printf("%d\n",sizeof(struct foo));
}



B2003

There is no such thing as either an object with size of 0 or a struct
with no members in the C language.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
J

Jack Klein

Sadly, I just jumped into the middle of this and spouted off the first
thing I could think of given the data that the sizeof foo was 0 in C.
Sorry for the noise.

No, it's not, there is no such thing in C. The grammar requires a
struct definition to contain at least one member definition.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
J

Jack Klein

Then it's undefined behaviour and there is no problem with the C program
outputting 0.

Not quite, it violates the grammar and thus requires a diagnostic. If
an executable is produced along with the diagnostic, the result is not
a C program so even the C term of "undefined behavior" does not really
apply.

No diagnostic means not compiled with a conforming C compiler, which
most compilers, not just gcc, are not by default.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
S

sg

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.

Well VC++ compiler has preprocessor #pragma with this you can control
the byte alignment.

#pragma pack(push, 1)
struct Test
{
char c;
int i;
};
#pragma pack(pop)

If you compile it using VC++ you will see the size 5

Regards
Sandeep
 
S

sg

When we compile the same program with c and c++, sizeof (Struct Foo)
is 0 and 1 respectively. Because in C++ it allocate some memory for
this pointer.

Regards
Sandeep
 
J

Juha Nieminen

sg said:
Well VC++ compiler has preprocessor #pragma with this you can control
the byte alignment.

#pragma pack(push, 1)
struct Test
{
char c;
int i;
};
#pragma pack(pop)

If you compile it using VC++ you will see the size 5

If you do that, expect a decrease in performance (because in most x86
architectures accessing an unaligned int will cause clock cycle penalties).
 
L

Lars Uffmann

Juha said:
#pragma pack(push, 1)
/* [...] */
#pragma pack(pop)

If you compile it using VC++ you will see the size 5

If you do that, expect a decrease in performance (because in most x86
architectures accessing an unaligned int will cause clock cycle penalties).

I think that was clear to Sandeep and it was just to demonstrate that
the sizeof(Test) only yields 8 due to the integer alignment :)

Best Regards,
Lars
 
B

Boltar

Did you pay attention to the compiler's warnings? Your example won't
even compile as C++.

I think you need to check you system since it compiles and runs fine
on mine:

morgoth$ cat t.cc
#include <stdio.h>

struct foo
{

};

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

}

morgoth$ g++ t.cc
morgoth$ ./a.out
1
morgoth$

B2003
 
J

James Kanze

Seems like it's not a legal declaration in C. From the C99 draft
standard:
A structure type describes a sequentially allocated
nonempty set of member objects (and, in certain
circumstances, an incomplete array), each of which has
an optionally specified name and possibly distinct
type.
VC++ correctly flags this as an error. I tried a few options
with gcc 3.3.1 but didn't get it to trigger a diagnostic. I
suggest discussing it over in comp.lang.c if you have further
interest.

His original code causes gcc 4.1.0 to output an error diagnostic
in both C and C++, if compiled in standards conformant mode
("gcc -std=c99 -pedantic" and "g++ -std=c++98 -pendantic"). In
both cases, because of the missing return type for main, and in
the case of C, because of an empty struct. (There's also an
option which will cause a diagnostic because of a type mismatch
in the call to printf.)
 
J

James Kanze

I think you need to check you system since it compiles and runs fine
on mine:
morgoth$ cat t.cc
#include <stdio.h>
struct foo
{
};
main()
{
printf("%d\n",sizeof(struct foo));
}
morgoth$ g++ t.cc

That doesn't invoke the gcc C++ compiler. To use the C++
compiler, you need:
g++ -std=c++98 -pedantic t.cc
And if you use that, it doesn't compile (at least with g++
4.1.0---nor with Sun CC 5.8).

Similarly, if you invoke the C compiler:
gcc -std=c99 -pedantic t.c
you get error messages as well.
 
J

James Kanze

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?

Because some architectures require a pointer to a structure to
be aligned on a multiple of 4 (or 6, or whatever) bytes. And
sizeof must take alignment considerations into account.
 
B

Boltar

That doesn't invoke the gcc C++ compiler. To use the C++

Rubbish. Of course it involkes the C++ compiler , what else is it
invoking , a pascal compiler?? If I replace struct with class it gives
the same result so its not calling the C compiler either. The fact
that it won't compile if you force it into pedantic mode is
irrelevant. With a standard invocation it will compile.

B2003
 
J

jkherciueh

Boltar said:
Rubbish. Of course it involkes the C++ compiler , what else is it
invoking , a pascal compiler??

It invokes a compiler that implements extensions to the C++ language as
permitted by the standard [1.4/8]. A compiler is allowed to compile invalid
code as per extensions although it has to issue a diagnostic (which could
be a warning).

If I replace struct with class it gives
the same result so its not calling the C compiler either. The fact
that it won't compile if you force it into pedantic mode is
irrelevant. With a standard invocation it will compile.

Irrelevant with regard to which question? The code above is invalid C++ as
per [7/7] and [3.6.1/2] regardless of whether the compiler of your choosing
happens to compile it.


Best

Kai-Uwe Bux
 
K

kwikius

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:

Are you sure that shouldnt be "...MAY not contribute..", at least in
pre C++0x? IIRC this is an optimisation that may be applied at the
discretion of the compiler, hence the moniker EBO or Empty Base class
Optimisation.

I believe that it is however unlikely that this optimisation won't be
applied on most compilers in practise..

(As for C++0x, I don't know, but if this isnt mandatory in pre C++0x
then making it mandatory in C++0x would appear to be a breaking
change, as potentially objects will change in size.)

regards
Andy Little
 
R

Ron Natalie

Boltar said:
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
{
};
The above is invalid in C and has at least size 1 in C++.
 
P

peter koch

Because some architectures require a pointer to a structure to
be aligned on a multiple of 4 (or 6, or whatever) bytes.  And
sizeof must take alignment considerations into account.
That is not the reason: just as with char, there is no reason to
require the alignment of an empty class to be a specific multiple of
anything but one.
My guess is that the requirement is there to allow compilers to always
have objects of class-type have a "convenient" size. I must admit,
that I can't see the reason for that but then I'm not a compiler
writer. All compilers I know have size of 1 for empty classes and
structs.

/Peter
 

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
474,184
Messages
2,570,973
Members
47,527
Latest member
RoxanneTos

Latest Threads

Top