On Sun, 13 Apr 2025 at 14:39, abdul rehman via Gcc-help <gcc-help@xxxxxxxxxxx> wrote: > > Dear GCC Team, > > I would like to bring to your attention an issue regarding the verbosity of > error messages in G++ when dealing with an invalid use of reference types > in STL containers. > > Consider the following minimal example: > > c++ > CopyEdit > #include <vector>void do_something() { N.B. There's something weird about the formatting of all your code examples. > std::vector<int&> v; > int j = 20; > v.push_back(j); > // Irrelevant code omitted. > } > > This code is *invalid by the C++ standard*, as std::vector<T> requires the > type T to be *CopyConstructible* and *Assignable*. Since int& is not an > object type and does not satisfy these requirements, this usage is > incorrect. The requirement actually comes from the allocator requirements, because allocators require an object type as their value type. > However, the compiler error produced by G++ is extremely verbose — > spanning *over > 200 lines* in some cases. It delves into internal template instantiations > and allocator machinery, with messages like the inability to create _Tp* > from int& inside new_allocator.h, followed by a cascade of > unrelated-looking errors. They're all related. And being unable to form a pointer to a reference is the fundamental problem here. You can't allocate memory for reference types. > Compare this to the following unrelated but invalid code: > > c++ > CopyEdit > #include <iostream>int main() { > int j = 20; > std::cout << j+* << std::endl; > return 0; > } > > This results in a clear and concise message: > > CopyEdit > $ g++ wrong.cpp > wrong.cpp: In function ‘int main()’: > wrong.cpp:4:22: error: expected primary-expression before ‘<<’ token It's certainly concise, but I'm not sure how clear it is. What's a primary-expression to the average user? > *Suggestion:* Could the diagnostic for invalid container types like > std::vector<int&> be made more user-friendly, perhaps by detecting > unsupported reference types early in template instantiation and emitting a > targeted error such as: > > error: std::vector<T> cannot be instantiated with T = int& because > reference types are not valid container elements No, because by the time std::vector<int&> is instantiated, std::allocator<int&> has already been instantiated and that's where most of the errors originate. We can put a static_assert in std::allocator so that the first error is clear, but it won't prevent the cascade of later errors. I don't agree with making the compiler treat std::vector<T&> as a special case with custom errors, because it would also be needed in all the other containers, and it wouldn't help for boost::container::vector<T&> or anything else incorrectly using std::allocator<T&>.