www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - typedef keyword?

reply bearophile <bearophileHUGS lycos.com> writes:
In D.learn I have just given an answer about alias/typedef, in it I have said
that the decision to deprecate typedef was in the end the right one:
http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learn&article_id=22387

But once some time is passed, what do you want to do with the typedef keyword?
Just remove it and turn its usage in a syntax error? Keep in mind that the
original purpose of typedefs in D was not imaginary, it was present to help a
real need. If you program a little in Pascal/ObjectPascal/Ada you quickly learn
that a typedef is useful.

So in my opinion a better solution is to design a better typedef, that uses the
"typedef" keyword, and supports a more flexible semantics, as Andrei has
suggested. This new usage of the "typedef" keyword may even be introduced in
D3, there's no need to rush. The usage of "alias this" in structs will help,
but a new usage of the typedef keyword may be syntax sugar for something else
defined in Phobos. This new syntax of typedef may require a () after the
keyword, to give space to specify the alternative kinds of typedef:
typedef(subtype) ... ...

The syntax typedef(...) is (I think) not syntactically compatible with C, so
there is no problem with introducing a similar syntax with different semantics
(this is even an improvement over D1, where typedef acts unlike C language).

Bye,
bearophile
Oct 20 2010
next sibling parent Antony <antonynoha yahoo.com> writes:
It looks like a good idea.

I program sometimes in Ada and i would be glad to see similar features in D as
well.

----------------------------
1) in Ada: type SomeType is
Oct 20 2010
prev sibling next sibling parent Michel Fortin <michel.fortin michelf.com> writes:
Personally, one thing I've used typedef for is for creating type-safe 
bindings for libraries in other languages. For instance, this C/C++ 
idiom:

	typedef struct A A;

essentially creates an undefined type, an opaque type that you can 
neither create nor access except through functions that knows about the 
definition of struct A. It's more often used with pointers and 
functions passed to and from functions:

	A *createA();
	void cookA(A *a);
	void deleteA(A *a);

But because it's declared but undefined. you can't allocate your own 
and pretend it's the right thing. This doesn't compile in C/C++:

	A *a1 = malloc(sizeof(A));
	A *a2 = new A;

This C/C++ code won't compile, and it mustn't because that's an opaque type.

Now, how do you allow the former (functions createA, cookA, deleteA) 
while disallowing the later (allocating your own A)? In the past in D I 
used typedef to do that.

	typedef void A;
	typedef void B;

Using typedef instead of alias prevents assignments of one pointer type 
to another while giving the desirable properties of an opaque type.

I'm not sure how to do that now without typedef: you can't declare a 
struct without defining it in D, so you can't prevent that dummy struct 
from being created and allocated and later passed to functions in your 
bindings, so there's no hope for make the such binding APIs compatible 
with SafeD.

-- 
Michel Fortin
michel.fortin michelf.com
http://michelf.com/
Oct 20 2010
prev sibling next sibling parent F.Almeida <francisco.m.almeida gmail.com> writes:
Extensions to turn typedef into a more useful construct have already
been proposed, but discussion on this has not evolved much since.

My first, naive, idea was shown here:
http://www.digitalmars.com/webnews/newsgroups.php?
art_group=digitalmars.D&article_id=114489

Both the syntax and the rules to enforce casting would need some
work, but the basic idea is give the programmer control over which
types such a variable can cast to and from.

== Quote from bearophile (bearophileHUGS lycos.com)'s article
 In D.learn I have just given an answer about alias/typedef, in it

the right one:
 http://www.digitalmars.com/webnews/newsgroups.php?

 But once some time is passed, what do you want to do with the

error? Keep in mind that the original purpose of typedefs in D was not imaginary, it was present to help a real need. If you program a little in Pascal/ObjectPascal/Ada you quickly learn that a typedef is useful.
 So in my opinion a better solution is to design a better typedef,

semantics, as Andrei has suggested. This new usage of the "typedef" keyword may even be introduced in D3, there's no need to rush. The usage of "alias this" in structs will help, but a new usage of the typedef keyword may be syntax sugar for something else defined in Phobos. This new syntax of typedef may require a () after the keyword, to give space to specify the alternative kinds of typedef:
 typedef(subtype) ... ...
 The syntax typedef(...) is (I think) not syntactically compatible

with different semantics (this is even an improvement over D1, where typedef acts unlike C language).
 Bye,
 bearophile

Oct 21 2010
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
I recently had a good use for a typedef. I was interfacing with some C
code (explicitly loaded DLL), and I've made a function which allows me
to create wrapper functions for C automatically and add error checking
code which throws an exception, but only if the return value of a C
function is supossed to return an error code. The function would
return a list of these wrapped functions as a string, and then I would
mixin the string in a class.

For example, I could have thse C functions:

// C code
LIBError SomeFunction(void) { }
int anotherFunction(void) { }

and my function would create a dynamic loading mechanism for both
functions and add error checking for SomeFunction, the result would be
mixed in and a possible output would be:

// D pseudocode, loading mechanism and function pointer not shown here
void someFunction()
{
    auto result = CSomeFunction();

    if (result != LIBErrors.NoError)
    {
        throw new LIBException("SomeFunction returned failure code.", result);
    }

    return result;
}

int anotherFunction(void)
{
    return CAnotherFunction();
}

The function would only generate the exception code if the return
value of the C function is "LIBError". The problem with this is that
LIBError was defined as an alias for a uint (this was autogenerated by
htod from a C header file). So my function couldn't differentiate
between a C function returning an int vs returning a LIBError, because
an alias doesn't introduce a new type and I don't know of any
introspection mechanism for detecting types that are aliased or not.
So using the "typedef int LIBError" trick I was able to differentiate
between C functions that return an int vs a LIBError, and put my mixin
generator function to good use.

On 10/21/10, F.Almeida <francisco.m.almeida gmail.com> wrote:
 Extensions to turn typedef into a more useful construct have already
 been proposed, but discussion on this has not evolved much since.

 My first, naive, idea was shown here:
 http://www.digitalmars.com/webnews/newsgroups.php?
 art_group=digitalmars.D&article_id=114489

 Both the syntax and the rules to enforce casting would need some
 work, but the basic idea is give the programmer control over which
 types such a variable can cast to and from.

 == Quote from bearophile (bearophileHUGS lycos.com)'s article
 In D.learn I have just given an answer about alias/typedef, in it

the right one:
 http://www.digitalmars.com/webnews/newsgroups.php?

 But once some time is passed, what do you want to do with the

error? Keep in mind that the original purpose of typedefs in D was not imaginary, it was present to help a real need. If you program a little in Pascal/ObjectPascal/Ada you quickly learn that a typedef is useful.
 So in my opinion a better solution is to design a better typedef,

semantics, as Andrei has suggested. This new usage of the "typedef" keyword may even be introduced in D3, there's no need to rush. The usage of "alias this" in structs will help, but a new usage of the typedef keyword may be syntax sugar for something else defined in Phobos. This new syntax of typedef may require a () after the keyword, to give space to specify the alternative kinds of typedef:
 typedef(subtype) ... ...
 The syntax typedef(...) is (I think) not syntactically compatible

with different semantics (this is even an improvement over D1, where typedef acts unlike C language).
 Bye,
 bearophile


Oct 21 2010