hidden passing of __FILE__ and __LINE__ into function

Solomon E via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Apr 18 06:28:06 PDT 2017


On Tuesday, 18 April 2017 at 10:13:09 UTC, Jonathan M Davis wrote:
> On Monday, April 17, 2017 07:23:50 Jonathan M Davis via 
> Digitalmars-d-learn wrote:
>> So, if you're okay with explicitly instantiating your variadic 
>> function template instead of having the types inferred, then 
>> it can work, but otherwise, no. Making it work would require a 
>> language enhancement
>
> Actually, not only is there already a bug report for this
>
> https://issues.dlang.org/show_bug.cgi?id=8687
>
> which is marked as a bug and not an enhancement, and when 
> Walter commented on it when an ICE related to it was fixed, he 
> didn't change it from a bug to an enhancement. So, it looks 
> like he agrees that it's a bug rather than considering it an 
> enhancement. It has yet to be fixed regardless though.
>
> - Jonathan M Davis

import std.stdio: writeln;
import std.conv: to;

void main()
{
     add("Scene 1", "Scene 2", "Scene 3");
     add("Scene 3", "Scene 4", "Scene 5");
     add(5, 6, 7);
     add(7, "Scene 8", "Scene 9");
     writeln("total scenes added: ", sceneCount);
}

struct Scene
{
     string name;
     string file;
     size_t line;
}

Scene*[] listOfScenes;
int[string] indexOfScenes;
int sceneCount = 0;

void add_impl(T...)(string file, size_t line, T args)
{
     foreach(arg; args)
     {
         static if (is(typeof(arg) == string))
         {
             auto name = arg;
         }
         else
         {
             auto name = "Scene " ~ arg.to!string;
         }
         if (name in indexOfScenes)
         {
             EError(file, line, "scene already exists", name);
         }
         else
         {
             indexOfScenes[name] = sceneCount;
             listOfScenes ~= new Scene(name, file, line);
             sceneCount += 1;
             writeln("added " ~ name);
         }
     }
}

void add(string file = __FILE__, size_t line = __LINE__, T...)(T 
args)
{
     add_impl!T(file, line, args);
}

void EError(string file, size_t line, string message, string name)
{
     writeln(name, ": ", message,
             " in file ", file, " in line ", line);
     auto previous = listOfScenes[indexOfScenes[name]];
     writeln("previous definition of ", previous.name,
             " was in ", previous.file, " in line ", 
previous.line);
}

/* output:

added Scene 1
added Scene 2
added Scene 3
Scene 3: scene already exists in file vlf.d in line 7
previous definition of Scene 3 was in vlf.d in line 6
added Scene 4
added Scene 5
Scene 5: scene already exists in file vlf.d in line 8
previous definition of Scene 5 was in vlf.d in line 7
added Scene 6
added Scene 7
Scene 7: scene already exists in file vlf.d in line 9
previous definition of Scene 7 was in vlf.d in line 8
added Scene 8
added Scene 9
total scenes added: 9

*/


I tried to produce an example of calling a function with
variadic template arguments using special tokens __FILE__ and 
__LINE__.

This compiles and runs, producing the output shown, using the 
default gdc
provided by Ubuntu 17.04. This appears to be a workaround for 
Issue 8687.
The instantiations of the wrapper function `add` should only add 
minimally
to the compiled object code size, once per call of `add`.
I'm not sure about the quality of any of this code.



More information about the Digitalmars-d-learn mailing list