Accessing __FILE__ and __LINE__ of caller in combination with varargs?

Simen Kjaeraas via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Apr 16 05:37:46 PDT 2016


On Saturday, 16 April 2016 at 00:03:59 UTC, Jonathan M Davis 
wrote:
> On Friday, April 15, 2016 20:52:42 WebFreak001 via 
> Digitalmars-d-learn wrote:

>> void assertf(string file = __FILE__, size_t line = __LINE__,
>> Args...)(lazy bool condition, in string message, Args args) {
>
> Yes, you can do that, but do _not_ do that unless you really 
> have no other choice. What you need to realize is that because 
> the file and line number arguments will be unique for every 
> call to this function, it will generate a new instantiation of 
> it _every_ time it is called. So, you're going to get a lot of 
> code bloat. There are rare cases where such bloat would be 
> acceptable, but in the general case, it's a terrible thing to 
> do. This particular case might be acceptable given how short it 
> is, but in general, using __FILE__ or __LINE__ as template 
> arguments should be avoided like the plague.

A few tricks to reduce this bloat:

- Write a small wrapper. This will still give bloat, but only of
small functions:

void assertf(string file = __FILE__, size_t line = __LINE__, 
Args...)(lazy bool condition, in string message, Args args) {
     assertfImpl(file, line, condition, message, args);
}

- Only care about line numbers in debug mode. Makes debug more 
bloated, code less readable, and you lose out on line numbers in 
release. Still worth it occasionally:

version (debug) {
     void foo(string file = __FILE__, size_t line = __LINE__, 
Args...)(Args args) {
         // Stuffs.
     }
} else {
     void assertf(Args...)(Args args) {
         // Stuffs.
     }
}

I'd love to have a way to pass the file and line number info as 
regular parameters, though. Something like:

void foo(Args...)(Args args, string file = __FILE__, int line = 
__LINE__) {}

Sadly, currently not possible. Maybe we could overload @disable 
for this purpose?

void foo(Args...)(Args args, @disable string file = __FILE__, 
@disable int line = __LINE__) {}

--
   Simen


More information about the Digitalmars-d-learn mailing list