www.digitalmars.com         C & C++   DMDScript  

D - typedef bug

reply "Jon Frechette" <jonf4 mindspring.com> writes:
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

This code is fine:

void foo( char [] word, out int[ char [] ] wordList )
{
  if ( word in wordList ){}
}

but this code:

typedef int[ char [] ] T;

void foo( char [] word, out T wordList )
{
  if ( word in wordList ){}
}

produces this error:

  "rvalue of in expression must be an associative array, not T"
Jul 29 2003
next sibling parent reply "Sean L. Palmer" <palmer.sean verizon.net> writes:
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Why "out"?  Surely you want to preserve the prior value of wordList?

Sean
  "Jon Frechette" <jonf4 mindspring.com> wrote in message =
news:bg5ulg$1lsh$1 digitaldaemon.com...
  This code is fine:

  void foo( char [] word, out int[ char [] ] wordList )
  {
    if ( word in wordList ){}
  }

  but this code:

  typedef int[ char [] ] T;=20

  void foo( char [] word, out T wordList )
  {
    if ( word in wordList ){}
  }

  produces this error:

    "rvalue of in expression must be an associative array, not T"
Jul 29 2003
parent reply "Jon Frechette" <jonf4 mindspring.com> writes:
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

No, the parameter wordList needs to be modified. If I had left the code =
snippet closer to the original code this would have been clearer.

void addWordToList( char [] word, out int[ char [] ] wordList )
{
  word =3D tolower( word );
  wordList[ word ]++;
  // other stuff
}

  "Sean L. Palmer" <palmer.sean verizon.net> wrote in message =
news:bg659t$1sit$1 digitaldaemon.com...
  Why "out"?  Surely you want to preserve the prior value of wordList?

  Sean
    "Jon Frechette" <jonf4 mindspring.com> wrote in message =
news:bg5ulg$1lsh$1 digitaldaemon.com...
    This code is fine:

    void foo( char [] word, out int[ char [] ] wordList )
    {
      if ( word in wordList ){}
    }

    but this code:

    typedef int[ char [] ] T;=20

    void foo( char [] word, out T wordList )
    {
      if ( word in wordList ){}
    }

    produces this error:

      "rvalue of in expression must be an associative array, not T"
Jul 30 2003
parent reply Burton Radons <loth users.sourceforge.net> writes:
Jon Frechette wrote:

 No, the parameter wordList needs to be modified. If I had left the code 
 snippet closer to the original code this would have been clearer.
  
 void addWordToList( char [] word, out int[ char [] ] wordList )
 {
   word = tolower( word );
   wordList[ word ]++;
   // other stuff
 }

Then you'll want to use "inout" because "out" clears the parameter to its initial value at the start of the function. Last I checked this wasn't in the prototype, and that's a bug. As is the error you reported. Russ was wrong - you have to explicitly cast to turn a base type into a typedef, but you can implicitly cast to turn a typedef into a base type. If your problem wasn't a bug, then it would be impossible to access or modify a typedef'd associative array! So, Walter, here's a bug report: typedef int [int] a; void foo () { 1 in a; } Compiling this with DMD 0.68 fails with the error message "f.d(5): rvalue of in expression must be an associative array, not a". It should compile.
Jul 30 2003
next sibling parent "Jon Frechette" <jonf4 mindspring.com> writes:
"Burton Radons" <loth users.sourceforge.net> wrote in message
news:bg862s$vur$1 digitaldaemon.com...
 Jon Frechette wrote:

 No, the parameter wordList needs to be modified. If I had left the code
 snippet closer to the original code this would have been clearer.

 void addWordToList( char [] word, out int[ char [] ] wordList )
 {
   word = tolower( word );
   wordList[ word ]++;
   // other stuff
 }

Then you'll want to use "inout" because "out" clears the parameter to its initial value at the start of the function. Last I checked this wasn't in the prototype, and that's a bug.

Something is wrong here because the addWordToList function is "working" as expected in my program. The wordList is not cleared on each call to the function. Is this a bug?
 As is the error you reported.  Russ was wrong - you have to explicitly
 cast to turn a base type into a typedef, but you can implicitly cast to
 turn a typedef into a base type.  If your problem wasn't a bug, then it
 would be impossible to access or modify a typedef'd associative array!

 So, Walter, here's a bug report:

     typedef int [int] a;

     void foo ()
     {
         1 in a;
     }

 Compiling this with DMD 0.68 fails with the error message "f.d(5):
 rvalue of in expression must be an associative array, not a".  It should
 compile.

Jul 31 2003
prev sibling parent reply "Walter" <walter digitalmars.com> writes:
"Burton Radons" <loth users.sourceforge.net> wrote in message
news:bg862s$vur$1 digitaldaemon.com...
 So, Walter, here's a bug report:

     typedef int [int] a;

     void foo ()
     {
         1 in a;
     }

 Compiling this with DMD 0.68 fails with the error message "f.d(5):
 rvalue of in expression must be an associative array, not a".  It should
 compile.

It should not compile, since a is a type, not a value.
Aug 01 2003
parent reply Burton Radons <loth users.sourceforge.net> writes:
Walter wrote:

 "Burton Radons" <loth users.sourceforge.net> wrote in message
 news:bg862s$vur$1 digitaldaemon.com...
 
So, Walter, here's a bug report:

    typedef int [int] a;

    void foo ()
    {
        1 in a;
    }

Compiling this with DMD 0.68 fails with the error message "f.d(5):
rvalue of in expression must be an associative array, not a".  It should
compile.

It should not compile, since a is a type, not a value.

My bad. DMD 0.68 under Windows XP: typedef int [int] aType; aType a; void foo () { 1 in a; } This fails compilation using "dmd f.d" with the error message "f.d(6): rvalue of in expression must be an associative array, not aType". It should compile.
Aug 01 2003
parent "Walter" <walter digitalmars.com> writes:
"Burton Radons" <loth users.sourceforge.net> wrote in message
news:bge8fs$s2i$1 digitaldaemon.com...
 My bad.  DMD 0.68 under Windows XP:

      typedef int [int] aType;
      aType a;

      void foo ()
      {
         1 in a;
      }

 This fails compilation using "dmd f.d" with the error message "f.d(6):
 rvalue of in expression must be an associative array, not aType".  It
 should compile.

Ok, I can take care of that one <g>.
Aug 02 2003
prev sibling parent reply Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
Jon Frechette wrote:
 This code is fine:
 
 void foo( char [] word, out int[ char [] ] wordList )
 {
   if ( word in wordList ){}
 }
  
 but this code:
  
 typedef int[ char [] ] T;
  
 void foo( char [] word, out T wordList )
 {
   if ( word in wordList ){}
 }
  
 produces this error:
 
   "rvalue of in expression must be an associative array, not T"

This behavior is intentional. When you typedef in D, it creates a new type, and the new type does not have implicit conversion with the old type. This is to prevent bad coding styles like this: HandleToSomething foo(); void bar() { int a = foo(); }; The person who calls foo() should store the return value as HandleToSomething, NOT as an int. True, in the current version of foo()'s library, maybe it is an int...but it could change to some other implementation in the future. If you have to do the conversion, then you can explicitly cast it: int b = (int)foo(); If you want a C-style typedef (where there are implicit casts defined), then in D you use an alias: alias int OtherHandleType; OtherHandleType c; ... int d = c; // this is ok, because it was an alias, not a typedef
Jul 29 2003
parent reply "Jon Frechette" <jonf4 mindspring.com> writes:
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
news:bg6k33$2c5k$1 digitaldaemon.com...
 Jon Frechette wrote:
 This code is fine:

 void foo( char [] word, out int[ char [] ] wordList )
 {
   if ( word in wordList ){}
 }

 but this code:

 typedef int[ char [] ] T;

 void foo( char [] word, out T wordList )
 {
   if ( word in wordList ){}
 }

 produces this error:

   "rvalue of in expression must be an associative array, not T"

This behavior is intentional. When you typedef in D, it creates a new type, and the new type does not have implicit conversion with the old type. This is to prevent bad coding styles like this: HandleToSomething foo(); void bar() { int a = foo(); }; The person who calls foo() should store the return value as HandleToSomething, NOT as an int. True, in the current version of foo()'s library, maybe it is an int...but it could change to some other implementation in the future. If you have to do the conversion, then you can explicitly cast it: int b = (int)foo(); If you want a C-style typedef (where there are implicit casts defined), then in D you use an alias: alias int OtherHandleType; OtherHandleType c; ... int d = c; // this is ok, because it was an alias, not a typedef

OK, I guess I understand this now. But then when would one want to use typedef instead of alias?
Jul 30 2003
parent Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
You use typdef when you want to create a new type that inherits its 
internal impelmentation from something else.  So you want to use typedef 
for things like handles, dev_t, size_t, and other things.  These are all 
types that are probably integers (or pointers) in their internal 
implementation, but generally you don't want the users to think of them 
that way.

You use alias when you just want a shortcut to access a type.  Like many 
of us alias 'bit' to 'bool' since the compler doesn't come with a 
builtin bool type.

Jon Frechette wrote:
 "Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
 news:bg6k33$2c5k$1 digitaldaemon.com...
 
Jon Frechette wrote:

This code is fine:

void foo( char [] word, out int[ char [] ] wordList )
{
  if ( word in wordList ){}
}

but this code:

typedef int[ char [] ] T;

void foo( char [] word, out T wordList )
{
  if ( word in wordList ){}
}

produces this error:

  "rvalue of in expression must be an associative array, not T"

This behavior is intentional. When you typedef in D, it creates a new type, and the new type does not have implicit conversion with the old type. This is to prevent bad coding styles like this: HandleToSomething foo(); void bar() { int a = foo(); }; The person who calls foo() should store the return value as HandleToSomething, NOT as an int. True, in the current version of foo()'s library, maybe it is an int...but it could change to some other implementation in the future. If you have to do the conversion, then you can explicitly cast it: int b = (int)foo(); If you want a C-style typedef (where there are implicit casts defined), then in D you use an alias: alias int OtherHandleType; OtherHandleType c; ... int d = c; // this is ok, because it was an alias, not a typedef

OK, I guess I understand this now. But then when would one want to use typedef instead of alias?

Jul 30 2003