2

I've recently started learning D version 1, using the Tango library. I decided to write a small class Dout that wraps tango.io.Stdout, except it overrides opShl to better match C++'s << style output. My implementation is like so:

// dout.d
module do.Dout;

import tango.io.Stdout;

class Dout
{
    public static Dout opShl(T) (T arg)
    {
        stdout(arg);
        return new Dout;
    }

    public static Dout newline()
    {
        stdout.newline;
        return new Dout;
    }
}

And in main, I make a simple call to Dout.opShl(), like so.

// main.d
import do.Dout;
import tango.io.Console;

int main(char[][] argv)
{
    Dout << "Hello" << " world!" << Dout.newline;
    Cin.get();
    return 0;
}

This works, but after pressing enter and exiting main, the text "do.Dout.Dout" is printed. After stepping through the code, I found that this text is printed at the assembly instruction:

00406B5C call __moduleDtor (40626Ch)

In which do.Dout's destructor is being called.

My question is, why is the module name being printed upon exiting main, and what can I do to stop this behaviour?

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Meta
  • 1,091
  • 6
  • 14
  • 2
    off-topic, but still related - D1 is not going to be developed further. D version 2 is the future, and I wholeheartedly recommend you chose that version instead, if you want to learn D. There is a project to port Tango to D2, so I guess the time you spend learning Tango won't be a waste of time. – DejanLekic Jan 12 '12 at 19:22
  • True; I decided to go with D1 specifically because I want to use Tango over Phobos; coming from a C++ background, I deemed that Tango would be a closer match. Once D2 is stable, I will definitely be switching over. – Meta Jan 12 '12 at 19:51
  • While this may be fun, do not overload the shift left operator for standard out. Also D1 is going to be developed until 2013. – he_the_great Jan 13 '12 at 02:30
  • @he_the_great I realize that this is a bad thing to do in actual code. I was just playing around, getting a feel for D's operator overloading. – Meta Jan 16 '12 at 17:18

1 Answers1

3

the reason "do.Dout.Dout" is printed is because Dout << Dout.newline; prints a new line (in the newline property call) and then attempts to print a human readable string of a Dout object (after it is passed to opShl!Dout())

and you only see it during destruction because then the output is flushed ;)

you should have done

__gshared Doutclass Dout = new Doutclass;

class Doutclass
{
    public Dout opShl(T) (T arg)
    {
        static if(T == NLine){
            stdout.newline;//if nl is passed do newline
        }else{
            stdout(arg);
        }
        return this;
    }

    struct NLine{}//this might need a dummy field to stop compiler complaints
    public static NLine newline()
    {
        return NLine();
    }
}

which is closer to the C style (Dout is an global object and doesn't get recreated each call, newline is a special struct that flushed the output besides adding a newline to it)

ratchet freak
  • 47,288
  • 5
  • 68
  • 106
  • I can't seem to get __gshared to work using DMD 1.0. Is this a 2.0 feature? The documentation is absent on the official website. – Meta Jan 19 '12 at 19:18
  • yeah it's a D2 feature check http://www.d-programming-language.org/migrate-to-shared.html you can do without __gshared – ratchet freak Jan 19 '12 at 20:33