While trying to write a class that times the duration between calling it's constructor and destructor, I ran into what I think is a bug in clang. (Edit: it's not a bug; it's implementation defined copy elision)
The timer struct below keeps a pointer to the duration object that's passed in as reference and adds the duration of the scope to this.
#include <iostream>
#include <chrono>
struct timer {
    using clock      = std::chrono::high_resolution_clock;
    using time_point = clock::time_point;
    using duration   = clock::duration;
    duration* d_;
    time_point start_;
    timer(duration &d) : d_(&d), start_(clock::now()) {}
    ~timer(){
        auto duration = clock::now() - start_;
        *d_ += duration;
        std::cerr << "duration: " << duration.count() << std::endl;
    }
};
timer::duration f(){
    timer::duration d{};
    timer _(d);
    std::cerr << "some heavy calculation here" << std::endl;
    return d;
}
int main(){
    std::cout << "function: " << f().count() << std::endl;
}
When compiling this with clang 7.0.0, the output is:
some heavy calculation here
duration: 21642
function: 21642
while for g++ 8 the output is
some heavy calculation here
duration: 89747
function: 0
In this case I do like clangs behavior, but from what I've found elsewhere the return value is supposed to be copied before destructors are run.
Is this a bug with Clang? Or does this depend on (implementation defined?) return value optimization?
The behavior is the same independent of whether the duration d in timer is a pointer or a reference.
--
I do realise that the compiler inconsistency can be solved by changing f so that the scope of the timer ends before the return, but that's beside the point here.
timer::duration f(){
    timer::duration d{};
    {
        timer _(d);
        std::cerr << "some heavy calculation here" << std::endl;
    }
    return d;
}
 
    