D - typedef bug
- "Jon Frechette" <jonf4 mindspring.com> Jul 29 2003
- "Sean L. Palmer" <palmer.sean verizon.net> Jul 29 2003
- "Jon Frechette" <jonf4 mindspring.com> Jul 30 2003
- Burton Radons <loth users.sourceforge.net> Jul 30 2003
- "Jon Frechette" <jonf4 mindspring.com> Jul 31 2003
- "Walter" <walter digitalmars.com> Aug 01 2003
- Burton Radons <loth users.sourceforge.net> Aug 01 2003
- "Walter" <walter digitalmars.com> Aug 02 2003
- Russ Lewis <spamhole-2001-07-16 deming-os.org> Jul 29 2003
- "Jon Frechette" <jonf4 mindspring.com> Jul 30 2003
- Russ Lewis <spamhole-2001-07-16 deming-os.org> Jul 30 2003
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
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
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
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
"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
"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
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
"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
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
"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
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









"Jon Frechette" <jonf4 mindspring.com> 