Connecting Tech Pros Worldwide Help | Site Map
 
 
LinkBack Thread Tools Search this Thread
  #1  
Old May 23rd, 2006, 12:35 PM
Ulrich Hobelmann
Guest
 
Posts: n/a
Default Compiled C vs C++

Hi, since I've done a bit of Java recently, I'm thinking of using some
C++ instead of C, just because the "class" syntax is looking more
convenient now.

One thing that makes me wonder is C++ code size though. I've heard that
C++ is supposed to be just a souped up C that makes you "pay as you go",
and I don't intend to go anywhere far. But a small toy class I wrote
generated much more code than the equivalent C struct, when instantiated
in a test main().

The C code did just what it was supposed to: malloc, fill some struct
fields and return. The C++ code generated two identical (!) constructor
functions that did about what the C one did. The calling code - of
course! - only called one of them, because on the syntax level there was
only one constructor. In addition, some kind of structure was generated
(I assume, the class), even though I don't have anything virtual, and I
don't see where code like I'm planning to write would ever need access
to the class structure.

So my question would be: why are there two constructors when I only
wrote one (even in the final, linked executable)? What/why is the funny
structure in the code? (compiler is GCC/G++ 4.0, but I'm sure 3.x isn't
much different/better)

I'm sure this is something of a FAQ (though Google didn't turn up any
really useful answer), so feel free to direct me to past posts.

Thanks,
Ulrich
  #2  
Old May 23rd, 2006, 12:55 PM
kwikius
Guest
 
Posts: n/a
Default Re: Compiled C vs C++

Ulrich Hobelmann wrote:

[...]

.... But a small toy class I wrote[color=blue]
> generated much more code than the equivalent C struct, when instantiated
> in a test main().[/color]

It would probably help to see the C++ code and C code you wrote,
including class equivalent C struct and main ()function. It might also
help to see the options (if any), you passed to the compiler.

regards
Andy Little

  #3  
Old May 23rd, 2006, 01:35 PM
mlimber
Guest
 
Posts: n/a
Default Re: Compiled C vs C++

Ulrich Hobelmann wrote:[color=blue]
> Hi, since I've done a bit of Java recently, I'm thinking of using some
> C++ instead of C, just because the "class" syntax is looking more
> convenient now.
>
> One thing that makes me wonder is C++ code size though. I've heard that
> C++ is supposed to be just a souped up C that makes you "pay as you go",
> and I don't intend to go anywhere far.[/color]

What do *you* mean by "pay as you go"?
[color=blue]
> But a small toy class I wrote
> generated much more code than the equivalent C struct, when instantiated
> in a test main().
>
> The C code did just what it was supposed to: malloc, fill some struct
> fields and return. The C++ code generated two identical (!) constructor
> functions that did about what the C one did. The calling code - of
> course! - only called one of them, because on the syntax level there was
> only one constructor. In addition, some kind of structure was generated
> (I assume, the class), even though I don't have anything virtual, and I
> don't see where code like I'm planning to write would ever need access
> to the class structure.[/color]

How do you know it generated two identical constructors? Because you
looked at the generated assembly? If it did generate a function that
you don't use (which seems more like a bug or inefficiency in your
compiler rather than a problem with the language as defined in the C++
standard), any linker since the 1970s will strip them from the final
executable. Likewise, where did you draw your information about the
mysterious structure that the compiler generated?
[color=blue]
> So my question would be: why are there two constructors when I only
> wrote one (even in the final, linked executable)? What/why is the funny
> structure in the code? (compiler is GCC/G++ 4.0, but I'm sure 3.x isn't
> much different/better)
>
> I'm sure this is something of a FAQ (though Google didn't turn up any
> really useful answer), so feel free to direct me to past posts.[/color]

As already requested, please post your code for both the comparable C
program and the C++ program. That will help us get to the bottom of
this.

Cheers! --M

  #4  
Old May 23rd, 2006, 01:45 PM
Victor Bazarov
Guest
 
Posts: n/a
Default Re: Compiled C vs C++

kwikius wrote:[color=blue]
> Ulrich Hobelmann wrote:
> [..] It might also
> help to see the options (if any), you passed to the compiler.[/color]

Not really. Compiler options discussions belong to the newsgroups
decidated to those compilers. Thanks for keeping this forum on topic.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


  #5  
Old May 23rd, 2006, 02:15 PM
Ulrich Hobelmann
Guest
 
Posts: n/a
Default Re: Compiled C vs C++

mlimber wrote:[color=blue]
> What do *you* mean by "pay as you go"?[/color]

That - as IIRC mentioned in Bruce Eckel's Book - I can use a class as a
struct; that a (non-virtual) function in the struct will be called as
efficiently as a C function, because it is fully, statically known at
compile-time. If everything is there, and I don't use more advanced
features, I don't see why the code should be different from C.

Interestingly so far it seems as if I could get *more* efficient code by
writing my own C++ to C compiler (remember the very first C++ compiler?)
than by using something as high-tech as GCC 4.
[color=blue]
> How do you know it generated two identical constructors? Because you
> looked at the generated assembly? If it did generate a function that
> you don't use (which seems more like a bug or inefficiency in your
> compiler rather than a problem with the language as defined in the C++
> standard), any linker since the 1970s will strip them from the final
> executable. Likewise, where did you draw your information about the
> mysterious structure that the compiler generated?[/color]

They were both in the assembler output (c++ -O2 -S) and in the final
executable, as I said. The source only has one constructor (see below),
but the translation has two. I can't even *guess* how any compiler
would get the idea of doing something like this...
[color=blue]
> As already requested, please post your code for both the comparable C
> program and the C++ program. That will help us get to the bottom of
> this.[/color]

Sure, here goes:

take something like
class Foo
{
public:
Foo(int n);
private:
int foo;
};

Foo::Foo(int n)
{
foo = n;
}

Clearly this could be done in C by declaring Foo a struct with one
member, and by either allocating it on the stack, or by mallocing it and
calling some init-function (i.e. constructor), like void initFoo(Foo *
f, int n);. That's what I'm expecting C++ to do as well, as I don't use
other features.

The output (PPC, trimmed):
__ZN3FooC2Ei:
LFB3:
stw r4,0(r3)
blr
LFE3:
.align 2
.globl __ZN3FooC1Ei
__ZN3FooC1Ei:
LFB4:
stw r4,0(r3)
blr

I.e. there are two constructors, and if I use one, AFAIK only one (the
one with the '1' in the name) is used. In this case it's just a few
bytes, but I'm wondering about the general case.
  #6  
Old May 23rd, 2006, 03:05 PM
Mehturt@gmail.com
Guest
 
Posts: n/a
Default Re: Compiled C vs C++

> I.e. there are two constructors, and if I use one, AFAIK only one (the[color=blue]
> one with the '1' in the name) is used. In this case it's just a few
> bytes, but I'm wondering about the general case.[/color]

just a guess.. isn't one of them copy-constructor that compiler
generates for you if you don't provide one?

  #7  
Old May 23rd, 2006, 03:45 PM
Bernd Strieder
Guest
 
Posts: n/a
Default Re: Compiled C vs C++

Hello

Ulrich Hobelmann wrote:
[color=blue]
> mlimber wrote:[color=green]
>> What do *you* mean by "pay as you go"?[/color]
>
> That - as IIRC mentioned in Bruce Eckel's Book - I can use a class as
> a struct; that a (non-virtual) function in the struct will be called
> as efficiently as a C function, because it is fully, statically known
> at
> compile-time. If everything is there, and I don't use more advanced
> features, I don't see why the code should be different from C.[/color]

At what price on the C side? See below.
[color=blue]
>
> Interestingly so far it seems as if I could get *more* efficient code
> by writing my own C++ to C compiler (remember the very first C++
> compiler?) than by using something as high-tech as GCC 4.[/color]

Try some real world sized examples. Try to support all features C++
offers, e.g. templates, exceptions, inheritance, overloading. Anything
else is comparing apples and oranges.

Taking the higher abstraction C++ offers out of consideration, it is
sure that C++ will have a few overheads at places a C programmer could
easily have done better. In the past the trend was more towards
improving speed than code size.
[color=blue]
> They were both in the assembler output (c++ -O2 -S) and in the final
> executable, as I said. The source only has one constructor (see
> below),
> but the translation has two. I can't even *guess* how any compiler
> would get the idea of doing something like this...[/color]

If you want to program against binary code you need an ABI (application
binary interface), defining what can be expected from binary code. If
some implementation detail requires two variants of a constructor to be
available, which in general are different, then both variants will be
produced so they are available at link time. Probably they will be
produced consistently for all classes, because it is an ABI.
[color=blue]
>[color=green]
>> As already requested, please post your code for both the comparable C
>> program and the C++ program. That will help us get to the bottom of
>> this.[/color][/color]
[color=blue]
> I.e. there are two constructors, and if I use one, AFAIK only one (the
> one with the '1' in the name) is used. In this case it's just a few
> bytes, but I'm wondering about the general case.[/color]

Then try the general case, find an example, where the other variant is
called. AFAIK gcc needs the second to implement inheritance, and other
C++ compilers are similar. After 20+ years there should be agreement on
the best way to implement something that basic.

Just in the case it helps, I think on some platforms there are
possibilities to remove unused code from the final binary at link time.


Bernd Strieder

  #8  
Old May 23rd, 2006, 03:55 PM
Ulrich Hobelmann
Guest
 
Posts: n/a
Default Re: Compiled C vs C++

Bernd Strieder wrote:[color=blue]
> Try some real world sized examples. Try to support all features C++
> offers, e.g. templates, exceptions, inheritance, overloading. Anything
> else is comparing apples and oranges.[/color]

Well, I don't really like templates or exceptions in C++, nor
overloading (but will of course use them if I'm supposed to write C++).

So that leaves me with inheritance, which is basically just passing
somebody a function pointer (or a set of function pointers, which is the
VMT).

Also, none of the above features implies that C++ should generate more
code than equivalent C.

I'm not criticizing C++'s feature set here ;) Just saying that it
should translate down to equivalent (not too readable maybe) C.
[color=blue]
> Taking the higher abstraction C++ offers out of consideration, it is
> sure that C++ will have a few overheads at places a C programmer could
> easily have done better. In the past the trend was more towards
> improving speed than code size.[/color]

Honestly, I don't think so. Most simple C++ features (not talking RTTI
or exceptions here) are 100% machine-translatable to equivalent C, I
would claim, with no overhead. It's just a few pointers and structs
here and there.
[color=blue]
> If you want to program against binary code you need an ABI (application
> binary interface), defining what can be expected from binary code. If
> some implementation detail requires two variants of a constructor to be
> available, which in general are different, then both variants will be
> produced so they are available at link time. Probably they will be
> produced consistently for all classes, because it is an ABI.[/color]

Ok, that'd be a valid reason.
[color=blue]
> Then try the general case, find an example, where the other variant is
> called. AFAIK gcc needs the second to implement inheritance, and other
> C++ compilers are similar. After 20+ years there should be agreement on
> the best way to implement something that basic.[/color]

But having a class BAR that inherits from class FOO is nothing different
from having a struct BAR including a struct FOO and implementing the
same functions, delegating to FOO's function as needed.

I don't need a second constructor. super() should simply call the
*usual* FOO constructor, I think.
[color=blue]
> Just in the case it helps, I think on some platforms there are
> possibilities to remove unused code from the final binary at link time.[/color]
  #9  
Old May 23rd, 2006, 03:55 PM
Ulrich Hobelmann
Guest
 
Posts: n/a
Default Re: Compiled C vs C++

Mehturt@gmail.com wrote:[color=blue][color=green]
>> I.e. there are two constructors, and if I use one, AFAIK only one (the
>> one with the '1' in the name) is used. In this case it's just a few
>> bytes, but I'm wondering about the general case.[/color]
>
> just a guess.. isn't one of them copy-constructor that compiler
> generates for you if you don't provide one?[/color]

That might be a real possibility. I totally forgot about copy
constructors...
  #10  
Old May 23rd, 2006, 04:35 PM
Noah Roberts
Guest
 
Posts: n/a
Default Re: Compiled C vs C++


Ulrich Hobelmann wrote:[color=blue]
> Bernd Strieder wrote:[color=green]
> > Try some real world sized examples. Try to support all features C++
> > offers, e.g. templates, exceptions, inheritance, overloading. Anything
> > else is comparing apples and oranges.[/color]
>
> Well, I don't really like templates or exceptions in C++, nor
> overloading (but will of course use them if I'm supposed to write C++).[/color]

"I don't like or use any of the features of this language so why is it
slower than another that doesn't have them?"

I think a better question is, why the hell did you pick it then?
[color=blue]
> I don't need a second constructor. super() should simply call the
> *usual* FOO constructor, I think.[/color]

We have no way of knowing how many times you called the copy
constructor or assignment operator as you didn't post anything that
uses the class you did post. Chances are high that a *newbie* like you
might do so without knowing.

I can't tell if you are trolling or really are this dumb.

  #11  
Old May 23rd, 2006, 04:55 PM
Jeff Flinn
Guest
 
Posts: n/a
Default Re: Compiled C vs C++

Ulrich Hobelmann wrote:[color=blue]
> mlimber wrote:[/color]

[color=blue]
> Interestingly so far it seems as if I could get *more* efficient code
> by writing my own C++ to C compiler (remember the very first C++
> compiler?) than by using something as high-tech as GCC 4.
>[color=green]
>> How do you know it generated two identical constructors? Because you
>> looked at the generated assembly? If it did generate a function that
>> you don't use (which seems more like a bug or inefficiency in your
>> compiler rather than a problem with the language as defined in the
>> C++ standard), any linker since the 1970s will strip them from the
>> final executable. Likewise, where did you draw your information
>> about the mysterious structure that the compiler generated?[/color]
>
> They were both in the assembler output (c++ -O2 -S) and in the final
> executable, as I said. The source only has one constructor (see
> below), but the translation has two. I can't even *guess* how any
> compiler would get the idea of doing something like this...
>[color=green]
>> As already requested, please post your code for both the comparable C
>> program and the C++ program. That will help us get to the bottom of
>> this.[/color]
>
> Sure, here goes:[/color]

[snipped incomplete code]
[color=blue]
> The output (PPC, trimmed):
> __ZN3FooC2Ei:
> LFB3:
> stw r4,0(r3)
> blr
> LFE3:
> .align 2
> .globl __ZN3FooC1Ei
> __ZN3FooC1Ei:
> LFB4:
> stw r4,0(r3)
> blr
>
> I.e. there are two constructors, and if I use one, AFAIK only one (the
> one with the '1' in the name) is used. In this case it's just a few
> bytes, but I'm wondering about the general case.[/color]

Assembly is not executable code. But if were talking assembly here's a
complete example and the complete corresponding assy from VC7.1 that shows
C++ is so efficient it doesn't generate any instructions for the class. ;-)

Without complete code one can be very mislead as to the meaning of results
taken out of context.

Jeff Flinn

foo.cpp
=======
class Foo
{
public:
Foo(int n):foo(n){}
private:
Foo();
int foo;
};


int main()
{

return 0;
}

foo.asm
=======
; Listing generated by Microsoft (R) Optimizing Compiler Version 13.10.3077

TITLE .\foo.cpp
.386P
include listing.inc
if @Version gt 510
..model FLAT
else
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA ENDS
CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS ENDS
$$SYMBOLS SEGMENT BYTE USE32 'DEBSYM'
$$SYMBOLS ENDS
$$TYPES SEGMENT BYTE USE32 'DEBTYP'
$$TYPES ENDS
_TLS SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS ENDS
; COMDAT _main
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
sxdata SEGMENT DWORD USE32 'SXDATA'
sxdata ENDS
FLAT GROUP _DATA, CONST, _BSS
ASSUME CS: FLAT, DS: FLAT, SS: FLAT
endif

INCLUDELIB LIBC

PUBLIC _main
; Function compile flags: /Ogtpy
; COMDAT _main
_TEXT SEGMENT
_main PROC NEAR ; COMDAT
; File c:\foo.cpp
; Line 15
xor eax, eax
; Line 16
ret 0
_main ENDP
_TEXT ENDS
END



  #12  
Old May 23rd, 2006, 07:35 PM
Ulrich Hobelmann
Guest
 
Posts: n/a
Default Re: Compiled C vs C++

Noah Roberts wrote:[color=blue]
> "I don't like or use any of the features of this language so why is it
> slower than another that doesn't have them?"
>
> I think a better question is, why the hell did you pick it then?[/color]

Because, as I said, C++ is *supposed* to be pay as you go. I think even
Bjarne Stroustrup himself said that if you don't know a feature (and
supposedly MANY C++ hackers don't know all features) and don't use it,
you shouldn't have to pay for it.

We're not talking of a language with a completely revolutionary runtime
model; we're talking about C plus syntactical features.
[color=blue][color=green]
>> I don't need a second constructor. super() should simply call the
>> *usual* FOO constructor, I think.[/color]
>
> We have no way of knowing how many times you called the copy
> constructor or assignment operator as you didn't post anything that
> uses the class you did post. Chances are high that a *newbie* like you
> might do so without knowing.[/color]

No, all I did was constructing an object.
[color=blue]
> I can't tell if you are trolling or really are this dumb.[/color]

Well, if this looks like a troll to you, feel free to ignore me.
  #13  
Old May 23rd, 2006, 07:55 PM
Alf P. Steinbach
Guest
 
Posts: n/a
Default Re: Compiled C vs C++

* Ulrich Hobelmann:[color=blue]
>
> take something like
> class Foo
> {
> public:
> Foo(int n);
> private:
> int foo;
> };
>
> Foo::Foo(int n)
> {
> foo = n;
> }
>
> Clearly this could be done in C by declaring Foo a struct with one
> member, and by either allocating it on the stack, or by mallocing it and
> calling some init-function (i.e. constructor), like void initFoo(Foo *
> f, int n);.[/color]

No, it can't be done in C. You can do in both C and C++ exactly what
you describe for C: it's not limited to C. But only with C++ can you
get a construction guarantee enforced by the compiler.

[color=blue]
> That's what I'm expecting C++ to do as well, as I don't use
> other features.
>
> The output (PPC, trimmed):
> __ZN3FooC2Ei:
> LFB3:
> stw r4,0(r3)
> blr
> LFE3:
> .align 2
> .globl __ZN3FooC1Ei
> __ZN3FooC1Ei:
> LFB4:
> stw r4,0(r3)
> blr
>
> I.e. there are two constructors, and if I use one, AFAIK only one (the
> one with the '1' in the name) is used. In this case it's just a few
> bytes, but I'm wondering about the general case.[/color]

If you don't want a copy constructor, declare one and don't implement it.

Usually you do want a copy constructor.

The linker should remove any unused functions, whether the object files
are generated by a C or C++ compiler, but that's a QOI issue.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
  #14  
Old May 24th, 2006, 03:35 AM
Ron House
Guest
 
Posts: n/a
Default Re: Compiled C vs C++

Noah Roberts wrote:
[color=blue]
> I can't tell if you are trolling or really are this dumb.[/color]

Remarks like that don't help anyone in understanding the language. I
think many people wonder whether C++ has unexpected inefficiencies,
whether of necessity or because of typically poor implementations, and
the OP posted a reasonable example of a test case. Other posters have
pointed out problems with it in a courteous manner. There are enough
genuine trolls, so I suggest you hold the insults for a few minutes, as
one is sure to come along soon.

--
Ron House house@usq.edu.au
http://www.sci.usq.edu.au/staff/house
  #15  
Old May 24th, 2006, 01:25 PM
Bernd Strieder
Guest
 
Posts: n/a
Default Re: Compiled C vs C++

Hello,

Ulrich Hobelmann wrote:
[color=blue][color=green]
>> If you want to program against binary code you need an ABI
>> (application binary interface), defining what can be expected from
>> binary code. If some implementation detail requires two variants of a
>> constructor to be available, which in general are different, then
>> both variants will be produced so they are available at link time.
>> Probably they will be produced consistently for all classes, because
>> it is an ABI.[/color]
>
> Ok, that'd be a valid reason.[/color]

Then it is valid, because it is the reason.
[color=blue]
>[color=green]
>> Then try the general case, find an example, where the other variant
>> is called. AFAIK gcc needs the second to implement inheritance, and
>> other C++ compilers are similar. After 20+ years there should be
>> agreement on the best way to implement something that basic.[/color]
>
> But having a class BAR that inherits from class FOO is nothing
> different from having a struct BAR including a struct FOO and
> implementing the same functions, delegating to FOO's function as
> needed.[/color]

That's what you think, but an object at an address and a subobject of an
object at an address are two different things. I think, there are many
ways to get all issues done, calculating offsets, handling exceptions,
and whatever, and one way requires two variants of every constructor by
default, which might be equal, but are not in the general case. To get
a stable ABI both versions are produced by default, although it might
seem stupid to do so in the special case.
[color=blue]
>
> I don't need a second constructor. super() should simply call the
> *usual* FOO constructor, I think.[/color]

You will have to try to solve the whole package of problems implementing
a C++ compiler to understand. Try to find a not so minimal example
spread across some translation units, where both variants of the
constructors are used, and try to understand why, or what would be more
difficult to achieve if another way had been chosen. I think the
example will have to include virtual functions to show anything
interesting, possibly even virtual inheritance. I do not know all the
details myself, but that's what I would try.

C++ has to offer quite some advantages, and it does so in a
architectured way, somehow using design patterns known before the times
of C++. If you read about design patterns, you will find the statement,
that architecture is about wasting at the right place. You are
objecting about a small wasted piece of a doghouse. The same idea
leading to a comparable piece in a skyscraper might save lots of
effort. I think you should find yourself a small house showing at least
a little bit of saving by that idea, instead of insisting on the
suboptimal doghouse. This group has seen lots of tries of proving C++
bad by doghouse examples. This is why you got so many responses you
don't like.

I think it is possible to fill several chapters introducing different
C++ implementations and comparing them. Basically this is what you are
asking for. Perhaps there is a book telling the story. (Design and
evolution of C++?). You simply cannot expect the whole deep story in a
newsgroup posting.

Bernd Strieder



 

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search

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 Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Popular Articles

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 205,338 network members.