Topic: Toward Opaque typedefs in C++0X


Author: mike.capp@gmail.com (Mike Capp)
Date: Thu, 4 Nov 2004 04:54:11 GMT
Raw View
I've just been reading this paper by Walter Brown
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1706.pdf,
linked to from the http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/
list) and the glaring omission of initialization puzzled me. There's
lots of discussion about how to make a safer type system, but no
mention of how to get anything into it in the first place. So we have
example code like

  typedef public int A;
  typedef public int B;
  A a, a2;
  B b;
  a = b; // error: the rhs B can't substitute for the lhs A
  a = a2; // ok

which is great but, assuming the author is not generally in the habit
of using uninitialized variables, looks a little fishy.

It looks as if the proposed rules implicitly forbid directly assigning
literals or named underlying-type values to opaquely-typedef'ed
variables. Hence

  typedef public int sprocket_count_t;
  int i = 1;
  sprocket_count_t a1 = 2; // error?
  sprocket_count_t a2 = i; // error?

would be illegal, and a static_cast or C-style cast would be required.
This seems undesirable. C-style casts are supposedly deprecated, and I
thought the point of making new-style casts so ugly was to discourage
them and make them stand out when they were absolutely necessary.
These goals fall rather flat if a shiny new safety feature requires us
to scatter them all over the place.

For variable initialization it's tempting to allow underlying-type
values to be assigned directly. Casts exist to demonstrate intent, and
when you have the decl type right there this seems redundant:

  sprocket_count_t c = 10; // no confusion about what '10' represents

Unfortunately, this argument doesn't apply so much to member
initialization lists; here, the initialization is widely separated
from the decl type, so the potential for confusion and error creeps
back in.

Has there been any followup discussion of this paper? The core idea
sounds like a real boon, but this initialization issue bothers me.

cheers,
Mike

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jm@bourguet.org (Jean-Marc Bourguet)
Date: Thu, 4 Nov 2004 22:32:41 GMT
Raw View
mike.capp@gmail.com (Mike Capp) writes:

> I've just been reading this paper by Walter Brown
> (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1706.pdf,
> linked to from the http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/
> list) and the glaring omission of initialization puzzled me. There's
> lots of discussion about how to make a safer type system, but no
> mention of how to get anything into it in the first place. So we have
> example code like
>
>   typedef public int A;
>   typedef public int B;
>   A a, a2;
>   B b;
>   a = b; // error: the rhs B can't substitute for the lhs A
>   a = a2; // ok
>
> which is great but, assuming the author is not generally in the habit
> of using uninitialized variables, looks a little fishy.
>
> It looks as if the proposed rules implicitly forbid directly assigning
> literals or named underlying-type values to opaquely-typedef'ed
> variables. Hence
>
>   typedef public int sprocket_count_t;
>   int i = 1;
>   sprocket_count_t a1 = 2; // error?
>   sprocket_count_t a2 = i; // error?
>
> would be illegal, and a static_cast or C-style cast would be required.
> This seems undesirable. C-style casts are supposedly deprecated, and I
> thought the point of making new-style casts so ugly was to discourage
> them and make them stand out when they were absolutely necessary.
> These goals fall rather flat if a shiny new safety feature requires us
> to scatter them all over the place.

There is a third notation for type conversion: the functional
notation.  So
sprocket_count_t a1 = sprocket_count_t(2);

That's look quite good to me.

> Clear, no For variable initialization it's tempting to allow
> underlying-type values to be assigned directly. Casts exist to
> demonstrate intent, and when you have the decl type right there this
> seems redundant:
>
>   sprocket_count_t c = 10; // no confusion about what '10' represents

> Unfortunately, this argument doesn't apply so much to member
> initialization lists; here, the initialization is widely separated
> from the decl type, so the potential for confusion and error creeps
> back in.

And I'm sure I don't want to start to think about how this would
interfere with overload resolution.  You put a litteral, you get a
function, you put a variable, you get another one...

> Has there been any followup discussion of this paper? The core idea
> sounds like a real boon, but this initialization issue bothers me.

I don't know.  I've given feedback (in french) to the french group but
couldn't go to the meeting since then got no news.

The major problem I found is that there would be too many functions
callable with the new types, so that would break the abstraction one
is trying to build.  A possible path for a solution is reducing the
number of functions to those which can be found in the namespace
searched by ADL (and introducing something equivalent for basic
types).

Something which would also be usefull for opaque typedefs is the
possibility to declare a class but define it as an opaque typedefs.
But that open a new can of worms for basic types.

Yours,

--
Jean-Marc

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Thu, 4 Nov 2004 22:29:45 GMT
Raw View
Mike Capp wrote:
>
> It looks as if the proposed rules implicitly forbid directly assigning
> literals or named underlying-type values to opaquely-typedef'ed
> variables. Hence
>
>   typedef public int sprocket_count_t;
>   int i = 1;
>   sprocket_count_t a1 = 2; // error?
>   sprocket_count_t a2 = i; // error?
>
> would be illegal, and a static_cast or C-style cast would be required.
> This seems undesirable. C-style casts are supposedly deprecated, and I
> thought the point of making new-style casts so ugly was to discourage
> them and make them stand out when they were absolutely necessary.
> These goals fall rather flat if a shiny new safety feature requires us
> to scatter them all over the place.
>
> For variable initialization it's tempting to allow underlying-type
> values to be assigned directly. Casts exist to demonstrate intent, and
> when you have the decl type right there this seems redundant:
>
>   sprocket_count_t c = 10; // no confusion about what '10' represents
>

I guess the issue could be resolved "as if" the type were an UDT with an
explicit constructor taking as parameter the underlying type. That is:

   sprocket_count_t c = 10; // illegal
   sprocket_count_t c(10);  // legal
   sprocket_count_t c = sprocket_count_t(10); // also legal

Notice that you don't need casts (neither C-style nor C++ style) as the
"functional notation" can safely be used and such notation is very clean
and descriptive, IMHO.

Alberto

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gdr@cs.tamu.edu (Gabriel Dos Reis)
Date: Fri, 5 Nov 2004 20:29:35 GMT
Raw View
jm@bourguet.org (Jean-Marc Bourguet) writes:

[...]

| Something which would also be usefull for opaque typedefs is the
| possibility to declare a class but define it as an opaque typedefs.

Oh no, you don't want that ;-)

| But that open a new can of worms for basic types.

Well, that open a new can of worms for many things, starting with
ABIs.


--
                                                        Gabriel Dos Reis
                                                         gdr@cs.tamu.edu
 Texas A&M University -- Department of Computer Science
 301, Bright Building -- College Station, TX 77843-3112

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]