www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - Mixins and auto

reply Chris Sauls <ibisbasenji gmail.com> writes:
Might be a bug, or might be me doing something silly, but this doesn't work as
expected:

# module mix0;
#
# import std.stdio ;
#
# class Foo {
#   this (char[] a_label) {
#     p_label = a_label;
#     writefln(" + ", p_label);
#   }
#
#   ~this () {
#     writefln(" - ", p_label);
#   }
#
#   private char[] p_label ;
# }
#
# template MFoo (char[] T_label) {
#   auto Foo _MFoo_foo = new Foo(T_label);
# }
#
# void main () {
#   { mixin MFoo!("A"); }
#   { mixin MFoo!("B"); }
#   { mixin MFoo!("C"); }
#
#   { auto Foo foo = new Foo("A2"); }
#   { auto Foo foo = new Foo("B2"); }
#   { auto Foo foo = new Foo("C2"); }
# }

The output I expected being:
  | + A
  | - A
  | + B
  | - B
  | + C
  | - C
  | + A2
  | - A2
  | + B2
  | - B2
  | + C2
  | - C2

The output I am getting:
  | + A
  | + B
  | + C
  | + A2
  | - A2
  | + B2
  | - B2
  | + C2
  | - C2
  | - C
  | - B
  | - A

Eh?  Apparently the "auto" variables declared by the mixins aren't getting
collected until 
the end of the entire function, my anonymous blocks be damned, and in reverse
order.  And 
in case anyone wonders, no it doesn't change if I place more code in the
blocks.  I ran 
across this little beaut looking for a way to conditionally compile in my Timer
objects 
with somewhat cleaner reading code. (I like the look of `mixin MTimer!("void
main()");` 
better than `version (Timer) auto Timer t = new Timer("void main()");` ... I
guess I'm crazy.)

Any insights?

-- Chris Sauls
Dec 10 2005
next sibling parent Sean Kelly <sean f4.ca> writes:
Chris Sauls wrote:
 Might be a bug, or might be me doing something silly, but this doesn't 
 work as expected:
 
 # module mix0;
 #
 # import std.stdio ;
 #
 # class Foo {
 #   this (char[] a_label) {
 #     p_label = a_label;
 #     writefln(" + ", p_label);
 #   }
 #
 #   ~this () {
 #     writefln(" - ", p_label);
 #   }
 #
 #   private char[] p_label ;
 # }
 #
 # template MFoo (char[] T_label) {
 #   auto Foo _MFoo_foo = new Foo(T_label);
 # }
 #
 # void main () {
 #   { mixin MFoo!("A"); }
 #   { mixin MFoo!("B"); }
 #   { mixin MFoo!("C"); }
 #
 #   { auto Foo foo = new Foo("A2"); }
 #   { auto Foo foo = new Foo("B2"); }
 #   { auto Foo foo = new Foo("C2"); }
 # }
 
 The output I expected being:
  | + A
  | - A
  | + B
  | - B
  | + C
  | - C
  | + A2
  | - A2
  | + B2
  | - B2
  | + C2
  | - C2
 
 The output I am getting:
  | + A
  | + B
  | + C
  | + A2
  | - A2
  | + B2
  | - B2
  | + C2
  | - C2
  | - C
  | - B
  | - A
 
 Eh?  Apparently the "auto" variables declared by the mixins aren't 
 getting collected until the end of the entire function, my anonymous 
 blocks be damned, and in reverse order.  And in case anyone wonders, no 
 it doesn't change if I place more code in the blocks.  I ran across this 
 little beaut looking for a way to conditionally compile in my Timer 
 objects with somewhat cleaner reading code. (I like the look of `mixin 
 MTimer!("void main()");` better than `version (Timer) auto Timer t = new 
 Timer("void main()");` ... I guess I'm crazy.)
 
 Any insights?

I think this is similar to auto variables not getting cleaned up if scope exits from a throw. In both cases, the dtor isn't being called as it should and they're being cleaned up by the next GC cycle. In the case of mixins however, it seems like a parse issue rather than a runtime issue. Sean
Dec 10 2005
prev sibling parent Thomas Kuehne <thomas-dloop kuehne.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Chris Sauls schrieb am 2005-12-10:
 Might be a bug, or might be me doing something silly, but this doesn't work as
expected:

 # module mix0;
 #
 # import std.stdio ;
 #
 # class Foo {
 #   this (char[] a_label) {
 #     p_label = a_label;
 #     writefln(" + ", p_label);
 #   }
 #
 #   ~this () {
 #     writefln(" - ", p_label);
 #   }
 #
 #   private char[] p_label ;
 # }
 #
 # template MFoo (char[] T_label) {
 #   auto Foo _MFoo_foo = new Foo(T_label);
 # }
 #
 # void main () {
 #   { mixin MFoo!("A"); }
 #   { mixin MFoo!("B"); }
 #   { mixin MFoo!("C"); }
 #
 #   { auto Foo foo = new Foo("A2"); }
 #   { auto Foo foo = new Foo("B2"); }
 #   { auto Foo foo = new Foo("C2"); }
 # }

 The output I expected being:
  | + A
  | - A
  | + B
  | - B
  | + C
  | - C
  | + A2
  | - A2
  | + B2
  | - B2
  | + C2
  | - C2

 The output I am getting:
  | + A
  | + B
  | + C
  | + A2
  | - A2
  | + B2
  | - B2
  | + C2
  | - C2
  | - C
  | - B
  | - A

 Eh?  Apparently the "auto" variables declared by the mixins aren't getting
collected until 
 the end of the entire function, my anonymous blocks be damned, and in reverse
order.  And 
 in case anyone wonders, no it doesn't change if I place more code in the
blocks.  I ran 
 across this little beaut looking for a way to conditionally compile in my
Timer objects 
 with somewhat cleaner reading code. (I like the look of `mixin MTimer!("void
main()");` 
 better than `version (Timer) auto Timer t = new Timer("void main()");` ... I
guess I'm crazy.)

 Any insights?

 -- Chris Sauls

Added to DStress as http://dstress.kuehne.cn/run/a/auto_13_A.d http://dstress.kuehne.cn/run/a/auto_13_B.d Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFDpgR53w+/yD4P9tIRAmEWAKDSygm+HzdO8DOMCWi80rjJ35Ss0ACgrylU kQb6vP4rIDdHKnVZg3Vteko= =tj/u -----END PGP SIGNATURE-----
Dec 18 2005