comp.lang.ada
 help / color / mirror / Atom feed
* C vs Ada code quality
@ 1997-04-24  0:00 Robert Dewar
  1997-04-26  0:00 ` Valentin Bonnard
  0 siblings, 1 reply; 5+ messages in thread
From: Robert Dewar @ 1997-04-24  0:00 UTC (permalink / raw)



Someone asked me, but I lost the email address, because it bounced, the
following (so I am not sure who asked)

<<Robert Dewar <dewar@merv.cs.nyu.edu> writes:

  > Valentin asks
  >
  > <<Can C beat Ada in theory for a given type of compiler (say pure
  > separate compilation - no inter-module annalysis / no
  > inter-procedure annalysis) ?>>
  >
  > If runtime checks are off, the answer is NO!

Suppose I want to define the constructor/destructor for a type. In
C++ I just define them. In Ada, I use the Finalisation type and
I (as far as I understand) overide them thus the object will have
tag (4 bytes long pointer ?); if the object is very small, this
can be significant.

Larger objects can slow down the program (larger blocks to allocate,
more cache miss, more page faults).

Ok this is a pretty small problem, but this is an example which
can be part of 'distributed fat' (many small overheads which
end-up slowing the program).

This problem explainned has perhaps a solution (other then not
using constructors/destructors) but this is just an idea.

Also, I understand that it may be difficult to compare different
compilers using different optimising methods.

Any reasons why Ada could be faster (in theory, no real numbers
required) then C or C++ when all checks are off ? ;-)
>>



A couple of important points here

C IS NOT THE SAME LANGUAGE AS C++ !

This confusion is an amazingly common one. I made a statement about C,
but the response assumes I was talking about C++, false! C++ has some
high level constructs that do not necessarily map identically into Ada,
so I would not make the same claim for C++ (that any program in C could
be mapped identically into Ada).

However, the example here is bogus. The contstructor/destructor mechanism
in C++ is entirely analogous to the controlled type facility in Ada 95.

There is nothing in Ada 95 that says that the tag is stored as part of
the value -- note that in formal RM terms, the tag is NOT part of the
value, and if you start thinking of it, even informally, as part of
the value, you will find the RM confusing (for example, an assignment
copies the value, but it does not copy the tag).

An implementation of destructors and constructors in C++ may or may not
add overhead to stored objects. An implementation of controlled types
in Ada 95 may or may not add overhead to stored objects. In any case
you are in the business of comparing implementations, not languages.

<<Any reasons why Ada could be faster (in theory, no real numbers
required) then C or C++ when all checks are off ? ;-)>>

Absolutely, consider the aliasing problem, in C, we write

  *q = 1;

and if q is a *int, then without very hard analysis that in any case can
never be entirely complete, we have to assume that any int values that
are temporarily in registers may be destroyed. There are many other cases
in which the "excessive" freedom of C pointers degrade the generated code.
Now this does not mean that an Ada compiler *will* do a better job, but
it means it could. For example, gcc does not do a very good job of aliasing
analysis (partly because it is not so useful for C), so GNAT does not see
this advantage -- but everyone knows that adding better aliasing analysis
and data structures to gcc would be helpful, even for C, and when this
is done, you will certainly be able to construct examples where Ada takes
advantage of this and does better than is possible in C.





^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: C vs Ada code quality
  1997-04-24  0:00 C vs Ada code quality Robert Dewar
@ 1997-04-26  0:00 ` Valentin Bonnard
  1997-04-26  0:00   ` Robert Dewar
  0 siblings, 1 reply; 5+ messages in thread
From: Valentin Bonnard @ 1997-04-26  0:00 UTC (permalink / raw)
  To: Robert Dewar


Robert Dewar <dewar@merv.cs.nyu.edu> writes:

> Someone asked me, but I lost the email address, because it bounced, the
> following (so I am not sure who asked)

Me, Valentin Bonnard, bonnardv@pratique.fr, and it shouldn't bounce 
(I have checked the from field was ok in the message I sent). 

> Ok this is a pretty small problem, but this is an example which
> can be part of 'distributed fat' (many small overheads which
> end-up slowing the program).

[...]

> Also, I understand that it may be difficult to compare different
> compilers using different optimising methods.
> 
> Any reasons why Ada could be faster (in theory, no real numbers
> required) then C or C++ when all checks are off ? ;-)
> >>
> 
> 
> 
> A couple of important points here
> 
> C IS NOT THE SAME LANGUAGE AS C++ !
>
> This confusion is an amazingly common one. I made a statement about C,
> but the response assumes I was talking about C++, false! 

I know that ! In fact this is about Ada vs The Rest of the Universe, 
that is, C and C++ ;-)

If you want, I can even tell you a list of incompatibillity betwen C
to C++ (all from memory).

> However, the example here is bogus. The contstructor/destructor mechanism
> in C++ is entirely analogous to the controlled type facility in Ada 95.

I'm not a specialist of Ada, but it seem to me that the analogy 
is imcomplete since C++ rely on overloading (compile time) 
and Ada on overiding (run time).

> There is nothing in Ada 95 that says that the tag is stored as part of
> the value -- note that in formal RM terms, the tag is NOT part of the
> value, and if you start thinking of it, even informally, as part of
> the value, you will find the RM confusing (for example, an assignment
> copies the value, but it does not copy the tag).

Ok, ok, like the dynamic type of an object in C++ (ie the 
vtable pointer - no, this word, vtable, is only there to 
annoy you).

> An implementation of destructors and constructors in C++ may or may not
> add overhead to stored objects. An implementation of controlled types
> in Ada 95 may or may not add overhead to stored objects. In any case
> you are in the business of comparing implementations, not languages.

No no no, I am *not* comparing a particular implementation, nor 
purely a std (the C and C++ std don't say anything about 
performance, I assume the Ada std doesn't either).

We are talking about performance in general; for example in C,
malloced data is slower than auto variable because free-store 
is slow and the stack goes fast; of course, there isn't 
anything in the C std about the fact that there will be a 
stack at run-time. You could even design a C interpretor 
where stack is not faster than malloc (if your interpretor 
still check the entire program for erroneous constructs 
at compile-time it can be conformant).

_Seriously_ destructors and constructors won't add any overhead 
in C++ whereas virtual functions will; and in my understanding 
of Ada 95 ctor and dtor (the 'controled' functions) are virtual 
(= dynamic dispatch) thus the overhead.

> <<Any reasons why Ada could be faster (in theory, no real numbers
> required) then C or C++ when all checks are off ? ;-)>>
> 
> Absolutely, consider the aliasing problem, in C, we write
> 
>   *q = 1;

Real arguments ! That's exacly what I asked for.

> and if q is a *int, then without very hard analysis 

'very hard' is correct (one would say impossible)

> that in any case can
> never be entirely complete, we have to assume that any int values that
> are temporarily in registers may be destroyed. 

Typically i counter (in for (i=a; i<b; i++)) aren't aliased and 
stay in register (otherwise we wouldn't be able to transform 
loops (for example loop unrolling)).

> There are many other cases
> in which the "excessive" freedom of C pointers degrade the generated code.

Any example ?

if (sizeof (int) == sizeof (long))
{
    long   l = 2;
    int    *p = reinterpret_cast<int*> (&l);
    *p = 1;
    cout << l;

is this what you mean by 'excessive freedom' ?

A compiler doesn't have to handle that and can put l in 
register and happily print 2 (rule to C++ programmers: 
remember that reinterpret_cast is nearly always unportable).

> Now this does not mean that an Ada compiler *will* do a better job, but
> it means it could. 

Ok

But is it different in Ada ? Does the 'aliased' keyword really 
help ? Does this keyword serve any purpose (the compiler can 
look at the source to see if you are taking accesses to a 
variable directly) ? Is it like the register keyword in C (ie 
the semantic of a register variable is the same but you can't 
take its address) ?

Thank you for your reply.

-- 

Valentin Bonnard
mailto:bonnardv@pratique.fr
http://www.pratique.fr/~bonnardv (Informations sur le C++ en Francais)




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: C vs Ada code quality
  1997-04-26  0:00 ` Valentin Bonnard
@ 1997-04-26  0:00   ` Robert Dewar
  1997-04-29  0:00     ` Richard Kenner
  0 siblings, 1 reply; 5+ messages in thread
From: Robert Dewar @ 1997-04-26  0:00 UTC (permalink / raw)



<<I know that ! In fact this is about Ada vs The Rest of the Universe>>

First, I am not quite sure what you mean by *this*! You were replying to
a thread which was specificaly discussing C and not C++. Second, I guess
you must have a very limited view of the universe if you think it only
contains Ada, C and C++ (do some investigation some time about what is
atually used for development these days, the entries for COBOL, Delphi,
Java, and especially Visual Basic may suprise you, not to mention the
4GL's.

<<I'm not a specialist of Ada, but it seem to me that the analogy
is imcomplete since C++ rely on overloading (compile time)
and Ada on overiding (run time).>>

Right, you are not a specialist in Ada, and your guesses are wrong. I will
say this again, quite clearly this time I hope: The controlled types in
Ada are exactly equivalent to the destructors in C++. They involve
dispatching only when it would also be neessary in C++. I don't know what
leads to your misconceptions here, but they are misconceptions.

Probably you are confusing the formal description with the implementation.
The fact that controlled types in Ada are derived from controlled does
not mean you have to implement them any differently from C++. 

<<Ok, ok, like the dynamic type of an object in C++ (ie the
  vtable pointer - no, this word, vtable, is only there to
  annoy you).>>

Huh? Why should the use of the word vtable annoy me? I know perfectly
well how typical implementations of of C++ use vtable pointers. You
should look sometime at the implementation of GNAT/C++ interfacing
which shows how vtable pointers are mapped into the GNAT/Ada 95
environment.

HOWEVER, the ie here is very wrong (ie means "that is"). A vtable is
not the dynamic type of the object. The latter is a formal semantic
concept in the language. A vtable is one possible implementation
approach. There is nothing in C++ that requires the use of the vtable
approach, and there are other possibilities.

<<No no no, I am *not* comparing a particular implementation>>

yes,yes,yes you *are* comparing a particular implementation. You just don't
realize what the distinction is between what is required in the semantics
and what a typical implementation uses to provide these semantics.

In both Ada and C++, finalization (destructors) are defined on individual
types, and have to be called at the right time. End of story, no significant
difference! Now you may wonder why in practice C++ implementations have
avoided the use of dynamic lists for finalization, and Ada implementations
have often used them. The answer is simple. Once you have to deal with
exceptions the dynamic list has real advantages -- the C++ world is
working through these problems now -- for example, see the discussions
with respect to g++ and exeptions, where recently someone seriously
suggested the possibility of going to lists for handling destructors.

<<But is it different in Ada ? Does the 'aliased' keyword really
help ? Does this keyword serve any purpose (the compiler can
look at the source to see if you are taking accesses to a
variable directly) ? Is it like the register keyword in C (ie
the semantic of a register variable is the same but you can't
take its address) ?>>

Of course not! You are forgetting separate compilation -- the same problem
of course arises in C. Yes, you can sometimes tell for local variables
(e.g. in the absence of subunits), but in C and C++ global variables
have to be assumed to be aliased, and this is not the case in Ada.






^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: C vs Ada code quality
  1997-04-26  0:00   ` Robert Dewar
@ 1997-04-29  0:00     ` Richard Kenner
  0 siblings, 0 replies; 5+ messages in thread
From: Richard Kenner @ 1997-04-29  0:00 UTC (permalink / raw)



In article <dewar.862056422@merv> dewar@merv.cs.nyu.edu (Robert Dewar) writes:
>Now you may wonder why in practice C++ implementations have
>avoided the use of dynamic lists for finalization, and Ada implementations
>have often used them. The answer is simple. Once you have to deal with
>exceptions the dynamic list has real advantages -- the C++ world is
>working through these problems now -- for example, see the discussions
>with respect to g++ and exeptions, where recently someone seriously
>suggested the possibility of going to lists for handling destructors.

Indeed it is my understanding that this was recently done in the GCC
development sources.




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: C vs Ada code quality
@ 1997-05-01  0:00 Valentin Bonnard
  0 siblings, 0 replies; 5+ messages in thread
From: Valentin Bonnard @ 1997-05-01  0:00 UTC (permalink / raw)
  To: Robert Dewar



Robert Dewar <dewar@merv.cs.nyu.edu> writes:

> <<I'm not a specialist of Ada, but it seem to me that the analogy
> is imcomplete since C++ rely on overloading (compile time)
> and Ada on overiding (run time).>>
> 
> Right, you are not a specialist in Ada, and your guesses are wrong. I will
> say this again, quite clearly this time I hope: The controlled types in
> Ada are exactly equivalent to the destructors in C++.

I don't understand how this can be.

> They involve
> dispatching only when it would also be neessary in C++. I don't know what
> leads to your misconceptions here, but they are misconceptions.

The fact that I believe that :

- tagged types can be used polymorphically thus have the vtable 
  pointer even if they aren't use polymorphically

- functions on tagged type are 'virtual', that is, they are 
  called based on the dynamic type

> Probably you are confusing the formal description with the implementation.
> The fact that controlled types in Ada are derived from controlled does
> not mean you have to implement them any differently from C++. 

Yes I assume they are implemented the same:

class Controled {
public:
    Controled ();
    // I don't how to write operator= here
    virtual ~Controled () = 0
        { } // if this syntax is allowed in C++, I'm not sure
};

This means that there is a runtime penatly in general for 
class derived from Controled (very localised and pretty 
small actually).

> <<No no no, I am *not* comparing a particular implementation>>
> 
> yes,yes,yes you *are* comparing a particular implementation. You just don't
> realize what the distinction is between what is required in the semantics
> and what a typical implementation uses to provide these semantics.

I am not; you are off base (or you want me to believe that).

Can you for example tell me an implementation which doesn't use 
a vtable ? (Of course details of the representation of the vtable 
can change a little.) Perhaps you know at special debugging 
implementation which doesn't use the vtable, but I'm talking 
about real compilers, not interpretors.

> In both Ada and C++, finalization (destructors) are defined on individual
> types, and have to be called at the right time. End of story, no significant
> difference! Now you may wonder why in practice C++ implementations have
> avoided the use of dynamic lists for finalization, and Ada implementations
> have often used them. The answer is simple. Once you have to deal with
> exceptions the dynamic list has real advantages -- the C++ world is
> working through these problems now -- for example, see the discussions
> with respect to g++ and exeptions, where recently someone seriously
> suggested the possibility of going to lists for handling destructors.

EH should be done with global walkback table; only the most 
basic implementation register the objects (the first 
implementation of EH in the first release that support it).

Modern EH doesn't slow down code that doesn't throw (or 
should I write raise, since we are in c.l.a ?); the other 
method, singnificatly easier to implement is that all 
object register and de-register all the time; this has 
an awfull abstraction penalty.

(Assuming exceptions are exceptionnals, which is true 
in real code in C++, but it is in Ada ?)

> <<But is it different in Ada ? Does the 'aliased' keyword really
> help ? Does this keyword serve any purpose (the compiler can
> look at the source to see if you are taking accesses to a
> variable directly) ? Is it like the register keyword in C (ie
> the semantic of a register variable is the same but you can't
> take its address) ?>>
> 
> Of course not! You are forgetting separate compilation -- the same problem
> of course arises in C. Yes, you can sometimes tell for local variables
> (e.g. in the absence of subunits), but in C and C++ global variables
> have to be assumed to be aliased, and this is not the case in Ada.

Ok, but for more flexible interfaces, shouldn't you declare 
everything aliased ?

Is Ada lower level than C/C++ in this respect (C++ 
programmers consider that the fact a variable is 
aliased is a low level detail) ? (While Ada 
operates at a clearly higher level than C/C++ wrt arg 
passing (IN/OUT vs T, T&, const T&, T*, const T* types).)

-- 

Valentin Bonnard
mailto:bonnardv@pratique.fr
http://www.pratique.fr/~bonnardv (Informations sur le C++ en Francais)




^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~1997-05-01  0:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-04-24  0:00 C vs Ada code quality Robert Dewar
1997-04-26  0:00 ` Valentin Bonnard
1997-04-26  0:00   ` Robert Dewar
1997-04-29  0:00     ` Richard Kenner
  -- strict thread matches above, loose matches on Subject: below --
1997-05-01  0:00 Valentin Bonnard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox