hidden passing of __FILE__ and __LINE__ into function

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Apr 17 03:55:30 PDT 2017


On Monday, April 17, 2017 10:30:35 Basile B. via Digitalmars-d-learn wrote:
> On Monday, 17 April 2017 at 10:22:47 UTC, Dmitry wrote:
> > Hi there.
> >
> > Currently for messages about errors I use code like this:
> >     void add(string name, ref Scene scene)
> >     {
> >
> >         if (name in listOfScenes)
> >         {
> >
> >             EError(__FILE__, __LINE__, "scene already
> >
> > exists".L, quoted(name));
> >
> >         }
> >
> >     ...
> >     }
> >
> > Is there way for avoid using (avoid writing) `__FILE__` and
> > `__LINE__` in each call? I.e. I want use simple
> >
> >     EError("scene already exists".L, quoted(name));
> >
> > but function `EError` must print info (file and line) of where
> > was called.
> >
> > P.S. `EError` just prints info into console, result for this
> >
> > example is:
> >> [Error] (source\core\EScene.d, 35) Scene already exists:
> >> "Scene 1"
> >
> > and code is:
> >     void EError(S...)(S args)
> >     {
> >
> >         write("[Error] (", args[0], ", ", args[1], ") ",
> >
> > args[2..$], '\n');}
> >
> >     }
>
> when used as template value parameter, __FILE__ and
> __LINE__evaluate to the file and line of the call site. So help
> yourself ans use something like this:
>
> void error(string f = __FILE__, int l = __LINE__)(string msg){}

They works, but it results in a new template being instantiated for every
call, so you really shouldn't use __FILE__ or __LINE__ as template arguments
if you can avoid it. Usually, the better way to handle it is to use runtime
arguments, e.g.

void error(string msg, string file = __FILE__, size_t line = __LINE__)
{
    ...
}

That's what Exception's constructor does as well as functions like
std.exception.enforce.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list