I was playing around with std::valarray and UndefinedBehaviorSanitizer, and noticed that std::begin an empty std::valarray causes undefined behavior. Here is the code:
#include <valarray>
int main() {
    std::valarray<int> a;
    std::begin(a);
}
To reproduce, compile the code with g++ -fsanitize=undefined and run the result executable.
Here is the std::begin implementation from libstdc++.
template<class _Tp>
  inline _Tp*
  begin(valarray<_Tp>& __va)
  { return std::__addressof(__va[0]); }
It seems that _val[0] creates an reference of null value for empty std::valarrays which causes the undefined behavior.
Is this a bug from libstdc++?
 
                        
n4659 - C++17 final working draft
so
a.begin()must be valid on an empty container.However
valarrayis defined in §29.7 Numeric arrays [numarray] from the §29 Numerics library [numerics] chapter so it's not directly part of the container library chapter.The
std::begin(valarray)is defined in §29.7.10 valarray range access [valarray.range] and here there is no mention of preconditions. Most relevant quotes hare are:So the question is if Table 83 applies here.
valarrayis described in §29.7.2 Class template valarray [template.valarray] and the standard says:Which seems to me to imply that
valarrayis a container falling under §26.2.1 General container requirementsTo me it looks like
std::beginon an emptyvalarrayshould be valid. On the other hand "Returns: An iterator referencing the first value in the array" could imply a precondition that thevalarraymust not be empty. So my only conclusion is that the standard should be more clear in this regard.