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