On May 16, 12:45 pm, Andy Lutomirski <
l...@amacapital.net> wrote:
> This has been annoying me for a while:
>
> #include <stddef.h>
>
> template<typename T>
> class Vec
> {
> public:
> Vec(size_t len) : len_(len) { data_ = new T[len]; }
> ~Vec() { delete data_; }
> Vec(const Vec &) = delete;
> void operator = (const Vec &) = delete;
>
> size_t size() const { return len_; }
> T &operator [] (size_t pos) { return data_[pos]; }
> private:
> size_t len_;
> T * data_;
> };
[...]
> template<typename T>
> void IncrementVec(Vec<T> &v)
> {
> for (size_t i = 0; i < v.size(); i++)
> ++v[i];
>
> }
[...]
> Are there any ways, idiomatic or otherwise, to tell a compiler (even in
> theory) that data_ can't point to len_? Adding a restrict qualifier to
> data_ has no effect in g++ (correctly AFAICT -- data_ isn't a function
> parameter).
An idiomatic solution to this particular problem? Call size() once
outside the loop, store the result in a local variable, and use the
local variable in the "for expression" instead of size().
Ex:
size_t n = v.size();
for (size_t i = 0; i < n; i++)
++v[i];
I'd expect a good compiler to be able to optimize that as opposed to
the old code. In the old code, a compiler couldn't (easily) know if
they were aliasing, but as soon as you create a new local variable,
escape analysis should be able to kick in and show that nothing
aliases the local variable. At least, that's what I'd expect on a good
compiler. Test of course. Also, I don't think this is what you wanted,
but it is an "idiomatic" way of solving this very particular problem.
That would be an interesting language feature though. I wonder how you
might specify it correctly and in such a way that it's useful as a
general purpose thing. Perhaps that restrict on a member X of a class
Y means that the member X and any directly or indirectly pointed-to or
contained objects of X will not alias any other member of Y for the
same Y object. Maybe.