Thread overview
Re: Evaluating __FILE__ and __LINE__ of caller?
Mar 03, 2012
Andrej Mitrovic
Mar 03, 2012
Adam D. Ruppe
Mar 03, 2012
Andrej Mitrovic
Mar 03, 2012
Adam D. Ruppe
Mar 03, 2012
Andrej Mitrovic
Mar 03, 2012
H. S. Teoh
Mar 03, 2012
Andrej Mitrovic
Mar 03, 2012
Andrej Mitrovic
Mar 03, 2012
Andrej Mitrovic
March 03, 2012
Well, there is a way but it might wreak havoc on your object size since it will instantiate a lot of templates. Therefore it would be a good thing to only do it in debug mode:

import std.string;

class A
{
    int opIndexDebug(int line = __LINE__, string file = __FILE__)(int x)
    {
        /* do a bunch of checks */
        throw new Exception(format("%s: %s", file, line));

        int value;
        /* compute value */
        return value;
    }

    debug
        alias opIndexDebug opIndex;
    else
        alias opIndexDebug!(__LINE__, __FILE__) opIndex;
}

void main()
{
    auto a = new A;
    auto b = a[1];
}

You see, when using debug mode it gets instantiated on every call site, whereas in release mode it uses one hardcoded template instance. Of course you might want the file/line in release mode too, in that case get rid of the aliases and just use the templated opIndex (but then again DMD doesn't merge templates so this could be a hit on performance).
March 03, 2012
On 3/3/12, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
>         throw new Exception(format("%s: %s", file, line));

That format is unnecessary but anywho. :)
March 03, 2012
Err wait a minute, that debug/else thing doesn't quite work well.. I thought it would.
March 03, 2012
Ok this works: http://paste.pocoo.org/show/560103/
March 03, 2012
On Saturday, 3 March 2012 at 01:46:05 UTC, Andrej Mitrovic wrote:
> Well, there is a way but it might wreak havoc on your object size since it will instantiate a lot of templates.


Since some time last year, it works on all functions, just
use regular default parameters:

// test9.d
import std.stdio;

void a(string file = __FILE__, int line = __LINE__) {
        writeln("called from ", file, ":", line);
}

void main() {
        a;
        a;
        a;
}
//
dmd test9
test9
called from test9.d:8
called from test9.d:9
called from test9.d:10
March 03, 2012
On 3/3/12, Adam D. Ruppe <destructionator@gmail.com> wrote:
> Since some time last year, it works on all functions, just use regular default parameters:

Right, but what about template bloat? DMD doesn't seem to merge these templates. It can try to inline them, but it's very easy to break the inliner. E.g.:

int myFunc(string file = __FILE__, int line = __LINE__)(int x)
{
    if (x == 1)
        return x;
    // missing else breaks inliner: Issue 7625
    return x + 1;
}

void main(string[] arg)
{
    if (arg.length)
    {
        x = myFunc(1);
    }
    else
    {
        x = myFunc(2);
    }
}

$ dmd -map -release -O -inline test.d
test.map:
 0002:00000054
_D4test34__T6myFuncVAyaa6_746573742e64Vi11Z6myFuncFiZi 00402054
 0002:00000058
_D4test34__T6myFuncVAyaa6_746573742e64Vi15Z6myFuncFiZi 00402058
March 03, 2012
On Saturday, 3 March 2012 at 02:19:55 UTC, Andrej Mitrovic wrote:
> Right, but what about template bloat?

You don't have to use templates at all. The __FILE__
and __LINE__ default params work in regular functions.

            // not a template, just regular parameters
void awesome(string file = __FILE__, int line = __LINE__) {
        printf("called from %s:%d", file, line);
}


They are passed as runtime parameters at the call site:

  push    dword ptr _TMP1@SYM32[09h] ; the file is pushed here
  push    dword ptr _TMP1@SYM32[0Bh]
  mov     EAX,8  ;  and the __LINE__ is here
   ; now it calls the function, note that it is the same
   ; call all three times
  call      _D5test97awesomeFAyaiZv@PC32
  push    dword ptr _TMP1@SYM32[01Fh]
  push    dword ptr _TMP1@SYM32[021h]
  mov     EAX,9
  call      _D5test97awesomeFAyaiZv@PC32
  push    dword ptr _TMP1@SYM32[035h]
  push    dword ptr _TMP1@SYM32[037h]
  mov     EAX,0Ah
  call      _D5test97awesomeFAyaiZv@PC32


No template bloat if you don't use a template!
March 03, 2012
Ah yeah, I forgot about those.
int opIndex(int x, int line = __LINE__, string file = __FILE__)

Tada. I overcomplicated.
March 03, 2012
On Sat, Mar 03, 2012 at 03:33:46AM +0100, Adam D. Ruppe wrote:
> On Saturday, 3 March 2012 at 02:19:55 UTC, Andrej Mitrovic wrote:
> >Right, but what about template bloat?
> 
> You don't have to use templates at all. The __FILE__
> and __LINE__ default params work in regular functions.
> 
>             // not a template, just regular parameters
> void awesome(string file = __FILE__, int line = __LINE__) {
>         printf("called from %s:%d", file, line);
> }
[...]

Cool! Thanks!


T

-- 
"Outlook not so good." That magic 8-ball knows everything! I'll ask about Exchange Server next. -- (Stolen from the net)