string file = __FILE__ considered harmful (and solution)

John Colvin john.loughran.colvin at gmail.com
Wed May 30 21:45:33 UTC 2018


On Wednesday, 30 May 2018 at 14:40:50 UTC, Steven Schveighoffer 
wrote:
> On 5/30/18 4:27 AM, FeepingCreature wrote:
>> There's a very common idiom where in order to report line 
>> numbers of an error or a log line at the callsite of a 
>> function, you pass __FILE__ and __LINE__ as default parameters:
>> 
>> void foo(string file = __FILE__, size_t line = __LINE__);
>> 
>> What's wrong with this?
>> 
>> Say you add a string parameter, such as
>> 
>> void foo(string msg, string file = __FILE__, size_t line = 
>> __LINE__);
>> 
>> foo("Hello World");
>> 
>> Now when you accidentally grab an old version of the library, 
>> your new code will still run, but it will believe that it's 
>> being called from file "Hello World", line 15. Not good.
>> 
>> Luckily there's a fix. Just stick this in some common header 
>> file in your project:
>> 
>> struct CallerInfo
>> {
>>    string file;
>>    size_t line;
>> }
>> 
>> void foo(string msg, CallerInfo caller = CallerInfo(__FILE__, 
>> __LINE__));
>> 
>> Now you cannot accidentally invoke foo with a string, or in 
>> fact any type except another instance of CallerInfo.
>
> Awesome idea! Unfortunately, it doesn't work. The __FILE__ and 
> __LINE__ there are not from the caller, but from the line that 
> defines foo.
>
> See here: https://run.dlang.io/is/siz9YZ
>

https://run.dlang.io/is/oMe7KQ

Less elegant, but solves the problem of accidental argument 
adding (CallerFile acts as a barrier). Unfortunately, while it 
works in theory, in practice the compiler crashes.... LOL


More information about the Digitalmars-d mailing list