Topic: Remove typedef ?


Author: scotts@ims.com (Scott Schurr)
Date: 1999/11/19
Raw View
In article <382E3072.53B4BD52@wizard.net>, "James Kuyper Jr." <kuyper@wizard.net> writes:
|> Valentin Bonnard wrote:
|> >
|> > James Kuyper Jr. wrote:
|> >
|> > > In C/C++ each pointer type can have a different representation, and
|> > > real implementations have in fact had different representations for some
|> > > types.
|> ....
|> > <rant>
|> > May I ask if such implementation really exist (today, not in 1980),
|> > and if any plans to have a C++ compiler ?
|>
|> I can't prove that there are any, but I'd be surprised if there were
|> none. However, both the C and C++ standards allow such implementations,
|> and will do
|> so for at least another decade. That's all that matters to me. YMMV.

As a matter of fact the SHARC DSP (Analog Devices) has seriously different
addressing schemes for their code space and their data space.  Pointer
subtraction between these two spaces makes no sense.  Additionally,
there are two different types of data pointers: those in data memory,
and those in program memory.

There is only a C compiler for this processor today.  But I've heard
rumblings of their tools group working on a C++ compiler.

--------------------------------------
Scott Schurr
  Integrated Measurement Systems, Inc.
  Voice: (503) 626-7117
  Fax:   (503) 644-6969
  Email: scotts@ims.com
--------------------------------------
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/11/16
Raw View
If you're going to insist on both sending a message by e-mail as well as
posting it to the newsgroup, please indicate so in each. I prefer not to
repeat my replies. I'd really prefer not getting the e-mail at all.

Valentin Bonnard wrote:
>
> James Kuyper Jr. wrote:
>
> > In C/C++ each pointer type can have a different representation, and
> > real implementations have in fact had different representations for some
> > types.
....
> <rant>
> May I ask if such implementation really exist (today, not in 1980),
> and if any plans to have a C++ compiler ?

I can't prove that there are any, but I'd be surprised if there were
none. However, both the C and C++ standards allow such implementations,
and will do
so for at least another decade. That's all that matters to me. YMMV.

....
> </realquestion>

You've got unmatched tags. Don't let such habits creep into your code
:-)
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Terje Sandstr m" <terje@osiris.no>
Date: 1999/11/13
Raw View
James Kuyper Jr. <kuyper@wizard.net> wrote in message
news:382B2606.1B07D3E6@wizard.net...
"Terje Sandstr   m" wrote:
>
> James Kuyper Jr. <kuyper@wizard.net> wrote in message
> news:3827918A.D1C85EFF@wizard.net...
.....
> > > possibly to forward declare it ???    I can't see any good reason for
> this,
> > > and none of your postings has touched upon this.  Anybody  have any
> comments
> > > on this ?
> >
> > I'm not sure what you mean. Could you give an example of what you'd like
> > to be able to do, and an explanation of how you would like it to work?
> >
>
> Assume one file with the following DEFINITIONS :
> class IntVector : public std::vector<int>
> {
>     ....................
> };
> and
> typedef std::vector<int>  INTVECTOR;
>
> Then in another file (h-file) some methods is DECLARED:
>
> class IntVector;
> void  func1 (IntVector&  param);

Note: the fact that you can forward declare classes and use them this
ways implies that all class pointers must have compatible
representations. That's not true of pointers in general.

I'm not sure what you mean here. Shouldn't "Pointers in general" be
represented the same way on a given implementation ??


> This is all that is needed for the declaration of func1, a forward
> declaration of class IntVector.
>
> However, if typedef should work equally, it should be written:
>
> typedef INTVECTOR;
> void func2(INTVECTOR& param);
>
> where the first line just DECLARES that there exist something called
> INTVECTOR, but nothing more.  As in the first case, that is all the
compiler
> needs to compile the function declaration.

Why do you need this function declaration, if you don't have the
definition of an INTVECTOR? You couldn't call it, because you couldn't
define an object of that type to pass to it. References are typically
implemented as functionally equivalent to pointers. Pointers to
different types might be different sizes, and might be passed by
different mechanisms. The compiler would have no idea how to compile the
function call, even if you could make one. You also couldn't use 'func2'
as a function pointer, because you don't know the full type of the
function. Functions with different signatures might have different
function pointer sizes or representations.

Could you extend your example by adding code which requires a
declaration in scope for func2(), without also requiring a definition
for INTVECTOR?

::::::::
The problem can arise in interface classes.  The interface class is an ABC,
with only pure virtual methods.
A given client may not use all the methods in the interface, thus, some
classes doesn't need to be defined in a given module.
As an example:

Assume class X  derived from an interface IX:
// In file X.h
#include "IX.h"
class A;

class X  : public IX
{
public:
 void otherFunc() const;
 void func(const A& a);
 X();
 virtual ~X();

};

Class A is defined in a separate A.h

// In file IX.h

class A;
class IX
{
public:
    virtual void func(const A& a) = 0;
    virtual void otherFunc() const = 0;
};

Then a class Y defined in
//  Y.h:
class IX;
class Y
{
public:
 void doSomething(const IX& x);
 Y();
 virtual ~Y();

};

// Implemented in Y.cpp
#include "Y.h"
#include "IX.h"

void Y::doSomething(const IX &x)
{
  x.otherFunc();
}

There is no need for Y.cpp to include A.h anywhere to compile.  The
implementation file X.cpp however, will need the A.h because it will use
class A.
You may argue that the IX interface should have been splitted into two
parts, but that's very often not practical.  The same forwarding argument
also applies to return types, pointer and reference members etc.
You can also find further arguments along the same way in Scott Meyers
"Efficient C++" item 34 - "Minimize compilation dependencies between files".
The whole point is to decouple the interface of a class from its
implementation, thus reducing compilation dependencies between modules.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/11/13
Raw View
You didn't set off the quoted sections from my message, which made your
answer hard to read. I've inserted '> ' where appropriate.

"Terje Sandstr=F8m" wrote:
>=20
> > James Kuyper Jr. <kuyper@wizard.net> wrote in message
> > news:382B2606.1B07D3E6@wizard.net...
> > "Terje Sandstr=F8m" wrote:
> > >
> > > James Kuyper Jr. <kuyper@wizard.net> wrote in message
> > > news:3827918A.D1C85EFF@wizard.net...
....
> > Note: the fact that you can forward declare classes and use them this
> > ways implies that all class pointers must have compatible
> > representations. That's not true of pointers in general.
>=20
> I'm not sure what you mean here. Shouldn't "Pointers in general" be
> represented the same way on a given implementation ??

No. In C/C++ each pointer type can have a different representation, and
real implementations have in fact had different representations for some
types. In particular, it's not uncommon for function pointers to be a
different size from object pointers. Implementations can have a byte
size smaller than the smallest addressable unit of memory by using 'char
*' pointers which contain both an address, and a byte offset within the
addressable unit. Pointers to larger objects would contain just the
address. There are real machines where the addressable unit is 32 bits,
and implementations of C on those machines which used such techniques to
fit 4 8-bit bytes into each addressable unit. sig_atomic_t is likely to
be 'int' on such machines.

....
> > Could you extend your example by adding code which requires a
> > declaration in scope for func2(), without also requiring a definition
> > for INTVECTOR?

> [Example showing use of a forward declaration of a class, rather
> than what I asked for.]

Your example used a forward declaration of a class, and relied for it's
feasibility upon the fact that all class pointers must have compatible
representations. In order for comparable code using forward declarations
of typedefs to be legal, all pointers to any type whatsoever would have
to be compatible. This would be a new requirement in the C/C++ world,
and would be a hardship for implementors in the contexts described
above.

For instance, on the machine with 32-bit addressable units, either bytes
would have to be 32 bits long, or all pointers would have to be large
enough for both an address and a byte offset - of course, this isn't
necessarily a problem if the size of an address is already at least 2
bits larger than is needed to store all possible addresses. On machines
with data addresses that are a different size than code addresses, all
pointers would have to be large enough to store addresses of either
type.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 1999/11/13
Raw View
James Kuyper Jr. wrote:

> In C/C++ each pointer type can have a different representation, and
> real implementations have in fact had different representations for some
> types.

> For instance, on the machine

<rant>
May I ask if such implementation really exist (today, not in 1980),
and if any plans to have a C++ compiler ?

In other word, aren't these arguments just some leftover from the
past, carried on by some standard bigots who can't catch up with
the real world ?
</realquestion>

--

Valentin Bonnard
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Terje Sandstr m" <tsandstr@online.no>
Date: 1999/11/11
Raw View
James Kuyper Jr. <kuyper@wizard.net> wrote in message
news:3827918A.D1C85EFF@wizard.net...
>
> Do you want 'typedef' to remain an alias, like it currently is, or do
> you want it to define a new type? You can't have both; they're
> incompatible concepts. Specifically - do you want the following to work:
>
> typedef double Double;
> void f(Double);
> double x=1.5;
>
> f(x);
>
> If your answer is "Yes", it's an alias. If it's "No", its a new type. An
> intermediate position is possible, I suppose: a typedef could be
> considered a distinct type with a trivial conversion to and from the
> type it's defined as. That would probably break some code, but not as
> much as would be broken if it were made a completely distinct type.
>

Today the typedef is an 'alias'-maker.  What I have noted is that many
programmers use the typedef'd value just like it was a class, except they
don't want the extra burden of defining the necessarry operations that has
not been derived.  What I'm asking is if these two should be separated, if
you want an alias - use one keyword, if you want a new type - use another
keyword, but which has not the same demands as deriving a new class, but
enforces the strong typing characteristics you also mention above.

> > which is a bit
> > like 'class', but without the other requirements of the 'class'.
> >
> > A type is not clearly defined in C++.  So neither is the behaviour of a
>
> It may not be clear, but it is very precise and detailed. See Section
> 3.9; it spends four pages defining what types are.
>

Shame on me, found the correct chapter, and you're right. Types are defined
clearly enough.  What I have called 'types' is what the standard calls
'fundamental types', wheras classes belongs to what the standard calls
'compound types'.

> > possibly to forward declare it ???    I can't see any good reason for
this,
> > and none of your postings has touched upon this.  Anybody  have any
comments
> > on this ?
>
> I'm not sure what you mean. Could you give an example of what you'd like
> to be able to do, and an explanation of how you would like it to work?
>

Assume one file with the following DEFINITIONS :
class IntVector : public std::vector<int>
{
    ....................
};
and
typedef std::vector<int>  INTVECTOR;

Then in another file (h-file) some methods is DECLARED:

class IntVector;
void  func1 (IntVector&  param);

This is all that is needed for the declaration of func1, a forward
declaration of class IntVector.

However, if typedef should work equally, it should be written:

typedef INTVECTOR;
void func2(INTVECTOR& param);

where the first line just DECLARES that there exist something called
INTVECTOR, but nothing more.  As in the first case, that is all the compiler
needs to compile the function declaration.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "TiTi" <Serra.Angel@Serra.Shrine>
Date: 1999/11/11
Raw View
Check Java's abstract Number class, and its derived classes (Integer,
Double, Boolean, ...). I believe SmallTalk has a similar approach.

TiTi






> Your point about not being able to derive from built-in types like
> int is a good one. The C++ committee discussed informally ways to
> allow derivation from built-in types, but elected not to do anything
> about it in the standard. The subject could be re-addressed in a
> future revision to the standard. In the mean time, maybe someone
> would like to implement such a language feature so we could have
> some experience with it before adding it to the language definition.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/11/12
Raw View
In article <382718FE.C1D71D9D@sun.com>, Steve Clamage
<stephen.clamage@sun.com> writes
>Your point about not being able to derive from built-in types like
>int is a good one.

However:

class Myint {
   int value;
public:
   Myint():value(0){};
   Myint(int v=0):value(v){}
   operator int(){return value;}
   virtual ~Myint(){}
};

and ones like it would seem to provide all the functionality of the
built-in type.  And any respectable compiler should generate efficient
code from it.

If you really do not want guaranteed initialisation you can remove the
initialiser from the default ctor.

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/11/12
Raw View
"Terje Sandstr=F8m" wrote:
>=20
> James Kuyper Jr. <kuyper@wizard.net> wrote in message
> news:3827918A.D1C85EFF@wizard.net...
....
> > > possibly to forward declare it ???    I can't see any good reason f=
or
> this,
> > > and none of your postings has touched upon this.  Anybody  have any
> comments
> > > on this ?
> >
> > I'm not sure what you mean. Could you give an example of what you'd l=
ike
> > to be able to do, and an explanation of how you would like it to work=
?
> >
>=20
> Assume one file with the following DEFINITIONS :
> class IntVector : public std::vector<int>
> {
>     ....................
> };
> and
> typedef std::vector<int>  INTVECTOR;
>=20
> Then in another file (h-file) some methods is DECLARED:
>=20
> class IntVector;
> void  func1 (IntVector&  param);

Note: the fact that you can forward declare classes and use them this
ways implies that all class pointers must have compatible
representations. That's not true of pointers in general.

> This is all that is needed for the declaration of func1, a forward
> declaration of class IntVector.
>=20
> However, if typedef should work equally, it should be written:
>=20
> typedef INTVECTOR;
> void func2(INTVECTOR& param);
>=20
> where the first line just DECLARES that there exist something called
> INTVECTOR, but nothing more.  As in the first case, that is all the com=
piler
> needs to compile the function declaration.

Why do you need this function declaration, if you don't have the
definition of an INTVECTOR? You couldn't call it, because you couldn't
define an object of that type to pass to it. References are typically
implemented as functionally equivalent to pointers. Pointers to
different types might be different sizes, and might be passed by
different mechanisms. The compiler would have no idea how to compile the
function call, even if you could make one. You also couldn't use 'func2'
as a function pointer, because you don't know the full type of the
function. Functions with different signatures might have different
function pointer sizes or representations.

Could you extend your example by adding code which requires a
declaration in scope for func2(), without also requiring a definition
for INTVECTOR?
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/11/09
Raw View
Terje wrote:
....
> The 'typedef' is used to define alias (synonyms) for other types and/or
> classes.  One can say it does this by defining a new type,

Do you want 'typedef' to remain an alias, like it currently is, or do
you want it to define a new type? You can't have both; they're
incompatible concepts. Specifically - do you want the following to work:

 typedef double Double;
 void f(Double);
 double x=1.5;

 f(x);

If your answer is "Yes", it's an alias. If it's "No", its a new type. An
intermediate position is possible, I suppose: a typedef could be
considered a distinct type with a trivial conversion to and from the
type it's defined as. That would probably break some code, but not as
much as would be broken if it were made a completely distinct type.

> which is a bit
> like 'class', but without the other requirements of the 'class'.
>
> A type is not clearly defined in C++.  So neither is the behaviour of a

It may not be clear, but it is very precise and detailed. See Section
3.9; it spends four pages defining what types are.

> type.   An integer (int) is a type, but a user-defined class is also a
> 'type'.   A typedef creates new types,

Not under the current standard, nor under any version of C.

....
> If a type is like a class, and in very many instances, a typedef is used to
> make a complex structure work like it was a class, why shouldn't it be

In C++, a typedef is exactly equivalent to the type it's defined as. If
the typedef "work[s] like it was a class" (whatever you mean by that),
then so does the "complex structure" it's defined as. Typedefs act as an
extra level of indirection in naming; they don't change the way that
anything works, except name lookup.

> possibly to forward declare it ???    I can't see any good reason for this,
> and none of your postings has touched upon this.  Anybody  have any comments
> on this ?

I'm not sure what you mean. Could you give an example of what you'd like
to be able to do, and an explanation of how you would like it to work?


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Steve Clamage <stephen.clamage@sun.com>
Date: 1999/11/09
Raw View
Terje wrote:
>
> The 'typedef' is used to define alias (synonyms) for other types and/or
> classes.  One can say it does this by defining a new type, which is a bit
> like 'class', but without the other requirements of the 'class'.

One can't say that. A typedef does not create a new type. It creates
only a new way to spell the name of an existing type. In all
respects
where both spellings are valid, the two spellings have the same
meaning.

A possible language design would have typedef create a new type. C
chose
not to do that, and C++ follows that decision. Aliases are useful
for
adding indirection. You can create new types in C++ if a new type
is what you want.

Your point about not being able to derive from built-in types like
int is a good one. The C++ committee discussed informally ways to
allow derivation from built-in types, but elected not to do anything
about it in the standard. The subject could be re-addressed in a
future revision to the standard. In the mean time, maybe someone
would like to implement such a language feature so we could have
some experience with it before adding it to the language definition.

--
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: deepblack@geocities.com (Luis Coelho)
Date: 1999/11/05
Raw View
On 02 Nov 99 04:53:12 GMT, "Terje Sandstr   m" <tsandstr@online.no>
uttered the following words:
>1.   A name created with a typedef can't be used in forwarding declarations.
>This forces you to include the definition of the typedef wherever you use
>it. Ex. try to use a reference or pointer to std::string without including
                                             ^^^^^^^^^^^^^
You mean std::basic_string<char>, don't you?

><string>.  This means that if your program uses typedefs, the files defining
>the typedefs will bind your source code files together.

;-)
Luis Coelho.
C++ Programming Language, 3rd Ed. by B. Stroustrup. My exercise answers at:
http://www.geocities.com/SiliconValley/Way/3972/index.html


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 1999/11/07
Raw View
On 02 Nov 99 04:53:12 GMT, "Terje Sandstrxm" <tsandstr@online.no>
uttered the following words:

> 1.   A name created with a typedef can't be used in forwarding declarations.
> This forces you to include the definition of the typedef wherever you use
> it. Ex. try to use a reference or pointer to std::string without including
> <string>.  This means that if your program uses typedefs, the files defining
> the typedefs will bind your source code files together.

I have a problem: code which uses the / operator with 0 as the
second argument fail with a division-by-zero error. I propose
that we remove the / operator.

--

Valentin Bonnard
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Vesa A J Karvonen <vkarvone@cc.helsinki.fi>
Date: 1999/11/07
Raw View
Terje Sandstr   m <tsandstr@online.no> wrote:
[snip]
> The typedef keyword
> creates an alias for another type/class, so that two names can be used for
> the same type/class. It may of course be nice to use a typedef to make a
> shorter name instead of a long tedious template name with all its
> parameters, but there are disadvantages with the typedef:
[snip]

To make a long story short, typedef is a construct that allows you to
have the extra level of indirection that you often need. You can create
simple but powerful abstractions using the typedef keyword. Making names
shorter may be convenient and practical, but it misses the point.

---
Vesa Karvonen


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Terje" <terje@osiris.no>
Date: 1999/11/08
Raw View
Thanks for the responses !

I note that this created quite a bit of reactions.  I will try to address
most of the comments in this posting, instead of answering to each
individually.

---------------

Ok, ok, ok,  it may be a bit hasty to remove the 'typedef' keyword
altogether.  My point, however, is that the typedef keyword doesn't match as
neatly into the object oriented space of C++ as one would like.  So instead
of removing it (got your attention with that, thought ;-), could it be
enhanced or changed to better fit with C++ ?   (I will still hold on to the
viewpoint that it has survived the transistion from C without some needed
changes.)

The 'typedef' is used to define alias (synonyms) for other types and/or
classes.  One can say it does this by defining a new type, which is a bit
like 'class', but without the other requirements of the 'class'.

A type is not clearly defined in C++.  So neither is the behaviour of a
type.   An integer (int) is a type, but a user-defined class is also a
'type'.   A typedef creates new types, but since the behaviour os these
types depends upon what the typedef refers to, the behaviour of the typedef
can't be anticipated just from the typedef keyword itself. You can't derive
a new type from an integer, but of course from your own class.  If you use
typedef for an integer, you can't derive from that typedef, but if you use
it for a class, you can.  This is what I mean with different behaviour.

If a type is like a class, and in very many instances, a typedef is used to
make a complex structure work like it was a class, why shouldn't it be
possibly to forward declare it ???    I can't see any good reason for this,
and none of your postings has touched upon this.  Anybody  have any comments
on this ?

--------------

A lot of the comments address the aliasing feature of 'typedef', two names
for one class.  Christopher Eltschka wrote about several other cases which
is equally bad.  Some of these will break the rules put up by Scott Meyer is
his "Efficent C++", and can also be caught by CodeWizard (and probably other
tools, too).  My point here is that the typedef case is equally bad, and
that one should be aware of possible errors with respect to this.

His other point about forward headers for the STL 'string' typedef (yes,
std::basic_string<char>, Luis C.) I find a good idea.  I would really like
to see forward headers for a lot more than iosfwd.

Global typedefs is a convenience that should be used very carefully, local
typedefs seems more harmless.  And I agree, that it covers up some of the
uglier part of the C++ declaration syntax.   Couldn't it then be an idea to
improve of that issue, so that one didn't have to use a typedef to cover
this up ???

The same point is also raised by TiTi, and I agree that using the typedef's
improves on the readability.  However, you may want to say that  TTMAP is a
new type, which one wants to use in several interface files.  One then needs
to include the definition of the typedef, when one ONLY really needs the
declaration.

Dave Harris comment on splitting typedef into two different keywords may be
one approach.  However, could it be possible to make a new stronger typedef
as part of a new standard ?   With a stronger typedef I mean that one
seperates out the different uses of the typedef, and makes that into
separate different keywords (or variations of the keyword), with each having
a more limited functionality than the cover-all typedef of today.




Terje Sandstr   m
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/11/03
Raw View
Terje Sandstr   m <tsandstr@online.no> wrote in message
news:iMnT3.583$Ux3.5443@news1.online.no...
> I find the typedef keyword more of a relic from the days of C, than
as a
> natural part of the object oriented C++ language.

I disagree. I think you see typedefs exclusively within the C context.
Typedef is an powerful means of expression, very powerful in the
context of C++. If you say:

typedef Something Yadda;

you introduced a type constant called Yadda in the enclosing name
space.

Much of the techniques in the STL rely on type definitions. Writing
complex generic libraries is next to unconceivable without leveraging
type definitions.


Typedefs are much more powerful than they seem.


Andrei




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Terje Sandstr m" <tsandstr@online.no>
Date: 1999/11/02
Raw View
I note there are several "items" which people denote as deprecated in C++,
and suggestions on removing these in the future. (See f.ex. the posting from
Abraxas software a few days ago.)
I have no problem with this, but I have not seen the typedef mentioned in
this connection.
I find the typedef keyword more of a relic from the days of C, than as a
natural part of the object oriented C++ language.  The typedef keyword
creates an alias for another type/class, so that two names can be used for
the same type/class. It may of course be nice to use a typedef to make a
shorter name instead of a long tedious template name with all its
parameters, but there are disadvantages with the typedef:

1.   A name created with a typedef can't be used in forwarding declarations.
This forces you to include the definition of the typedef wherever you use
it. Ex. try to use a reference or pointer to std::string without including
<string>.  This means that if your program uses typedefs, the files defining
the typedefs will bind your source code files together.

2.  Having two names for the same thing seems to me to ask for confusion. If
you want to use the typedef for making your programs more readable, then the
opposite may happen when the method

doSomething(Whatever & athing);

 is used with

Something  aDifferentThing;
doSomething(aDifferentThing);

Deep down in your h-files a "typedef Whatever Something" exists that allows
this, but you have no clue about this when you read the code.

To live without the typedef keyword  forces you to think a bit more before
coding. Repeating  long templated names may easily cause difficult compiler
errors, but instead of using the typedef, you could inherit a new class from
the template, thus avoing the typedef issue all together.

I have seen the typedef causing problems, like the ones mentioned above, in
several large scale projects I'm been involved with.

So, now I wonder what other people think about the typedef keyword, and what
kind of experience other people have had with the typedef keyword.

Should it be removed ?


Best regards

Terje  Sandstr   m,  M.Sc.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/11/03
Raw View
"Terje Sandstr=F8m" wrote:
....
> So, now I wonder what other people think about the typedef keyword, and=
 what
> kind of experience other people have had with the typedef keyword.
>=20
> Should it be removed ?

Please indicate how to implement functionality equivalent to size_t,
std::iterator_traits or std::allocator<T>::rebind without the use of
typedefs.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Michiel Salters <salters@lucent.com>
Date: 1999/11/03
Raw View
"Terje Sandstr=F8m" wrote:

> I note there are several "items" which people denote as deprecated in C=
++,
> and suggestions on removing these in the future. (See f.ex. the posting=
 from
> Abraxas software a few days ago.)
> I have no problem with this, but I have not seen the typedef mentioned =
in
> this connection.
> I find the typedef keyword more of a relic from the days of C, than as =
a
> natural part of the object oriented C++ language.  The typedef keyword
> creates an alias for another type/class, so that two names can be used =
for
> the same type/class. It may of course be nice to use a typedef to make =
a
> shorter name instead of a long tedious template name with all its
> parameters, but there are disadvantages with the typedef:
 =

> 1.   A name created with a typedef can't be used in forwarding declarat=
ions.
> This forces you to include the definition of the typedef wherever you u=
se
> it. Ex. try to use a reference or pointer to std::string without includ=
ing
> <string>.  This means that if your program uses typedefs, the files def=
ining
> the typedefs will bind your source code files together.

However, these files should be quite stable - any change to them ought to=

cause a major rebuild of your program. Creating huge header files with
many tasks is for other reasons besides typedef's a bad idea.

> 2.  Having two names for the same thing seems to me to ask for confusio=
n. If
> you want to use the typedef for making your programs more readable, the=
n the
> opposite may happen when the method

> doSomething(Whatever & athing);

>  is used with

> Something  aDifferentThing;
> doSomething(aDifferentThing);

> Deep down in your h-files a "typedef Whatever Something" exists that al=
lows
> this, but you have no clue about this when you read the code.

This is of course not a problem. Either a "Whatever" is a "Something", or=
 not.
If not, the typedef is incorrectly used, else the behavior should be expe=
cted.

> To live without the typedef keyword  forces you to think a bit more bef=
ore
> coding. Repeating  long templated names may easily cause difficult comp=
iler
> errors, but instead of using the typedef, you could inherit a new class=
 from
> the template, thus avoing the typedef issue all together.

As if that solves problem 2 above - you will now have to watch out if a =

doSomething(Something&) is added. This will change behavior. With the typ=
edef,
you can't add two overloads for one (logical) type.

> So, now I wonder what other people think about the typedef keyword, and=
 what
> kind of experience other people have had with the typedef keyword.

> Should it be removed ?

No. Across classes it is quite essential - typedef is needed for e.g. STL=

container iterators. Deriving classes from the allocator's iterator would=

cause tremendous code bloat, too - The compiler would be forced to genera=
te
duplicate code for all but equal classes, differing only in name.

We can also look at char_traits<>. Again, without iterators this is askin=
g
for troubles.

> Best regards
> Terje  Sandstr=F8m,  M.Sc.

Michiel Salters
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: scorp@btinternet.com (Dave Harris)
Date: 1999/11/03
Raw View
tsandstr@online.no (Terje Sandstr   m) wrote:
> So, now I wonder what other people think about the typedef keyword, and
> what kind of experience other people have had with the typedef keyword.

Sometimes I want a new type, and sometimes I want a new name for an
existing type. Not having a good mechanism for doing the former is a
problem, but typedef is still needed for the latter.

Ideally we might have 2 keywords, eg:
    typedef - define a new type.
    typename - give a new name to an existing type.

although for backwards compatibility typedef is unlikely to change now.


> Repeating  long templated names may easily
> cause difficult compiler errors, but instead of using the typedef,
> you could inherit a new class from the template, thus avoing the
> typedef issue all together.

This doesn't work well when the template base has many constructors.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 1999/11/03
Raw View
Terje Sandstr=F8m wrote:

> Should [typedef] be removed ?

The headers read=20

  X-Original-Date: Mon, 1 Nov 1999 22:42:13 +0100

Hum, I am missing something ?

--=20

Valentin Bonnard
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "TiTi" <TJunkMeBigTime@mad.dog.com>
Date: 1999/11/03
Raw View
I think (and I presume a lot of others too) typedef enables you to define
types in a clean, readable fashion. When declaring variables of a certain
complex type (e.g. template classes with a lot of (template) parameters,
pointers to arrays of member functions, ...), it is certainly easier, and
more understandable, to use typedefs first to make the declaration trivial.
This comment can be found in the (ISO/IEC) C++ standard.

For example:



[BEGIN CODE]
#include <map>
#include <string>
using namespace std;

class A
{
public:
 void f1(int,int) {}
 void f2(int,int) {}
 void f3(int,int) {}
};

typedef void (A::*func_type_A)(int, int);

typedef map<string, int, less<int>, allocator<string> > TTMAP;

int main(void)
{
 // pointer section: which is the most readable?
 func_type_A   Afuncs[3] = {&A::f1, &A::f2, &A::f3};
 void (A::*q[3])(int, int) = {&A::f1, &A::f2, &A::f3};

 // template section: which is the most readable?
 TTMAP ttmap1 = TTMAP();
 map<string, int, less<int>, allocator<string> > ttmap2 = map<string, int, less<int>, allocator<string> >();

  return 0;
}
[END CODE]



I think I made my point. "Typedef" should *never* be removed!



TiTi









Terje Sandstr   m <tsandstr@online.no> wrote in message news:iMnT3.583$Ux3.5443@news1.online.no...
> I note there are several "items" which people denote as deprecated in C++,
> and suggestions on removing these in the future. (See f.ex. the posting from
> Abraxas software a few days ago.)
> I have no problem with this, but I have not seen the typedef mentioned in
> this connection.
> I find the typedef keyword more of a relic from the days of C, than as a
> natural part of the object oriented C++ language.  The typedef keyword
> creates an alias for another type/class, so that two names can be used for
> the same type/class. It may of course be nice to use a typedef to make a
> shorter name instead of a long tedious template name with all its
> parameters, but there are disadvantages with the typ
edef:
> 1.   A name created with a typedef can't be used in forwarding
declarations.
> This forces you to include the definition of the typedef wherever you use
> it. Ex. try to use a reference or pointer to std::string without including
> <string>.  This means that if your program uses typedefs, the files
defining
> the typedefs will bind your source code files together.
> 2.  Having two names for the same thing seems to me to ask for confusion.
If
> you want to use the typedef for making your programs more readable, then
the
> opposite may happen when the method
> doSomething(Whatever & athing);
>  is used with
> Something  aDifferentThing;
> doSomething(aDifferentThing);
> Deep down in your h-files a "typedef Whatever Something" exists that
allows
> this, but you have no clue about this when you read the code.
> To live without the typedef keyword  forces you to think a bit more before
> coding. Repeating  long templated names may easily cause difficult
compiler
> errors, but instead of using the typedef, you could inherit a new class
from
> the template, thus avoing the typedef issue all together.
> I have seen the typedef causing problems, like the ones mentioned above,
in
> several large scale projects I'm been involved with.
> So, now I wonder what other people think about the typedef keyword, and
what
> kind of experience other people have had with the typedef keyword.
> Should it be removed?
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Pete Becker <petebecker@acm.org>
Date: 1999/11/03
Raw View
"Terje Sandstr=F8m" wrote:
>=20
> So, now I wonder what other people think about the typedef keyword, and=
 what
> kind of experience other people have had with the typedef keyword.
>=20
> Should it be removed ?
>=20

No. Think about how you would write vector<int>::iterator if the library
didn't supply a typedef for it.

--=20
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/11/03
Raw View
"Terje Sandstr=F8m" wrote:
>=20
> I note there are several "items" which people denote as deprecated in C=
++,
> and suggestions on removing these in the future. (See f.ex. the posting=
 from
> Abraxas software a few days ago.)
> I have no problem with this, but I have not seen the typedef mentioned =
in
> this connection.
> I find the typedef keyword more of a relic from the days of C, than as =
a
> natural part of the object oriented C++ language.  The typedef keyword
> creates an alias for another type/class, so that two names can be used =
for
> the same type/class. It may of course be nice to use a typedef to make =
a
> shorter name instead of a long tedious template name with all its
> parameters, but there are disadvantages with the typedef:
>=20
> 1.   A name created with a typedef can't be used in forwarding declarat=
ions.
> This forces you to include the definition of the typedef wherever you u=
se
> it. Ex. try to use a reference or pointer to std::string without includ=
ing
> <string>.  This means that if your program uses typedefs, the files def=
ining
> the typedefs will bind your source code files together.

This is easily solved with "forward headers" like iosfwd.
BTW, you are not allowed to forward-declare any standard class
anyway.

>=20
> 2.  Having two names for the same thing seems to me to ask for confusio=
n. If
> you want to use the typedef for making your programs more readable, the=
n the
> opposite may happen when the method
>=20
> doSomething(Whatever & athing);
>=20
>  is used with
>=20
> Something  aDifferentThing;
> doSomething(aDifferentThing);
>=20
> Deep down in your h-files a "typedef Whatever Something" exists that al=
lows
> this, but you have no clue about this when you read the code.

Or deep down in your .h files, there may be a conversion defined
that allows this, but you have no clue about this when you read
the code.
Or deep down in your .h files, Something may be derived from
Whatever, but you have no clue...
Or deep down in your .h files, there may be another definition
of doSomething(Something&), but you have no clue...
Or deep down in your .h files, there may be a template for
doSomething, but you have no clue...
Or Something may have been imported by "using namespace Foo;",
and somewhere deep down in your .h files, there may be a
definition of Foo::doSomething(Something*), but you have noe clue...
Or deep down in your .h files, there may be a macro doSomething,
but you have no clue...

To make it short: If you don't have a clue what's in your headers,
then you'll have a hard time reading the code that uses them.
This is in no way specific to typedefs.

>=20
> To live without the typedef keyword  forces you to think a bit more bef=
ore
> coding. Repeating  long templated names may easily cause difficult comp=
iler
> errors, but instead of using the typedef, you could inherit a new class=
 from
> the template, thus avoing the typedef issue all together.

And possibly breaking your code:

template<class T1, class T2> class S { ... };

template<class T>
 void foo(T&)
{
  general algorithm
};

template<class T1, class T2>
 void foo(S<T1, T2>&)
{
  specialized algorithm
};

typedef S<int, int> S1;

class S2: public S<double, double> {};

int main()
{
  S1 s1; foo(s1); // uses specialized algorithm
  S2 s2; foo(s2); // uses general algorithm
}

If you are lucky, you're just doubling your runtime.
If you are unlucky, it won't work anymore (f.ex. an
algorithm specialized for auto_ptr, taking special
care about temporaries, even if it slows down the
algorithm - the derived class will use the inappropriate
general algorithm)

But you can even break your code more silently, f.ex. by
deleting through a pointer to the template, when you allocated
an item of your "typedef" class.

>=20
> I have seen the typedef causing problems, like the ones mentioned above=
, in
> several large scale projects I'm been involved with.
>=20
> So, now I wonder what other people think about the typedef keyword, and=
 what
> kind of experience other people have had with the typedef keyword.
>=20
> Should it be removed ?

Clearly: No.

While global typedefs are just a convenience, typedefs local to
templates are an important part of generic programming.
How would you code iterator_traits<some_iterator>::value_type
without typedefs?

Also, typedefs can help a lot to avoid the ugliest corners of
C++ declaration syntax. Or can you immediatly understand the
following?

void (*f(void(*)()))();

(I hope I didn't make a mistake).

Compare with

typedef void (*pvoidfun)();
pvoidfun f(pvoidfun);

And no, you can't derive from void(*)().

Last not least, think about the amount of code that would break
if you removed typedefs (f.ex. most of the standard library).
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Stephen Clamage <stephen.clamage@sun.com>
Date: 1999/11/03
Raw View
"Terje Sandstr=F8m" wrote:
> =

> I find the typedef keyword more of a relic from the days of C, than as =
a
> natural part of the object oriented C++ language.  The typedef keyword
> creates an alias for another type/class, so that two names can be used =
for
> the same type/class. It may of course be nice to use a typedef to make =
a
> shorter name instead of a long tedious template name with all its
> parameters, but there are disadvantages with the typedef:
> =

> 1.   A name created with a typedef can't be used in forwarding declarat=
ions. ...
> =

> 2.  Having two names for the same thing seems to me to ask for confusio=
n. ...

Typedefs also serve as a mechanism for abstraction.

For example, suppose you want an integer type that is big enough for
some purpose, but no larger. Since the integer types vary in size on
different systems, you can't necessarily solve this problem by picking
one specific type. By putting a typedef in a project-wide header, you
need modify only one line of code when porting to different systems.
In addition, you can give the integer type a meaningful name.

I don't think there is another mechanism that achieves  those results so
neatly. The alternative of creating an integer class or a replacement
enum type is too cumbersome.

Also consider the reverse of using two names for one class: one name
for two classes. You might have alternative implementations of some
type,
either your own, or some OS abstraction. (Unix systems sometimes have
different representations of time.) When you want to choose among the
alternatives and are not affected by differences in interface, you can
use a single typedef to select one. You could write a class wrapper, but
sometimes a typedef is all you need.

-- =

Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]