boost::noncopyable errors are difficult to diagnose on MSVC

Is there anything that can be done to improve the error messages generated by the compiler when a copy fails to be made due to a boost::noncopyable? I had just finished a sprint where I had typed close to 1,000 lines of code with tons of new classes and objects before trying to compile, and one of the classes I had entered was similar to the following: class foo { public: foo(boost::asio::ip::tcp::socket& socket) : socket_(socket) { } private: boost::asio::ip::tcp::socket socket_; }; Problem here is that I forgot to add a reference to the class member, it was by value so the compiler is going to generate an error since a socket cannot be copied. The error this generated from the compiler was: 1>Q:\include\boost\1.39.0\boost/asio/basic_io_object.hpp(92) : error C2248: 'boost::noncopyable_::noncopyable::noncopyable' : cannot access private member declared in class 'boost::noncopyable_::noncopyable' 1> Q:\include\boost\1.39.0\boost/noncopyable.hpp(27) : see declaration of 'boost::noncopyable_::noncopyable::noncopyable' 1> Q:\include\boost\1.39.0\boost/noncopyable.hpp(22) : see declaration of 'boost::noncopyable_::noncopyable' 1> This diagnostic occurred in the compiler generated function 'boost::asio::basic_io_object<IoObjectService>::basic_io_object(const boost::asio::basic_io_object<IoObjectService> &)' 1> with 1> [ 1> IoObjectService=boost::asio::stream_socket_service<boost::asio::ip::tcp> 1> ] The most I can possibly figure out from this is that it's related to a socket. but this hardly helped as I had been using socket stuff all over the place. It took a long time to track this down because there was zero information about even what source file the offending code was in. I know this is sort of catering to the compiler, but is there any trickery that can be done so that at least the compiler generates an error related to the source file the object was declared in?

On Fri, Nov 6, 2009 at 9:44 AM, Zachary Turner <divisortheory@gmail.com> wrote:
Is there anything that can be done to improve the error messages generated by the compiler when a copy fails to be made due to a boost::noncopyable?
Easy cure is to spell out the private declarations for the copy constructor and the assignment operator "by hand". We all know that this spells "non-copyable". Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

On Fri, Nov 6, 2009 at 1:17 PM, Emil Dotchevski <emildotchevski@gmail.com> wrote:
On Fri, Nov 6, 2009 at 9:44 AM, Zachary Turner <divisortheory@gmail.com> wrote:
Is there anything that can be done to improve the error messages generated by the compiler when a copy fails to be made due to a boost::noncopyable?
Easy cure is to spell out the private declarations for the copy constructor and the assignment operator "by hand". We all know that this spells "non-copyable".
Because of C++0x deleted functions, the idiom for noncopyable is going to change. class foo { foo( const foo & ) = delete; foo & operator =( const foo & ) = delete; ... }; Maybe Boost should have a macro, say BOOST_NONCOPYABLE(T), that would generate the above for C++0x compilers, and the following for pre-C++0x compilers: class foo { foo( const foo & ); foo & operator =( const foo & ); ... }; What the user would actually write would be: class foo { BOOST_NONCOPYABLE(foo) ... }; Another approach would be for the user to write: class foo { foo( const foo & ) BOOST_DELETED_FUNC; foo & operator =( const foo & ) BOOST_DELETED_FUNC; ... }; For 0x it would generate =delete while for non-0x it would generate nothing. --Beman

On Fri, Nov 6, 2009 at 5:13 PM, Beman Dawes <bdawes@acm.org> wrote:
On Fri, Nov 6, 2009 at 1:17 PM, Emil Dotchevski <emildotchevski@gmail.com> wrote:
On Fri, Nov 6, 2009 at 9:44 AM, Zachary Turner <divisortheory@gmail.com> wrote:
Is there anything that can be done to improve the error messages generated by the compiler when a copy fails to be made due to a boost::noncopyable?
Easy cure is to spell out the private declarations for the copy constructor and the assignment operator "by hand". We all know that this spells "non-copyable".
Because of C++0x deleted functions, the idiom for noncopyable is going to change. [...]
Interesting stuff, however... I'm not sure if any of that will help the errors. I haven't tried any experiments, but It looks to me that even if the compiler tells you exactly what class is not copyable, it doesn't tell you where the attempted copy is taking place. And I'm not sure if anything but a compiler fix will make it better. Tony

On Fri, Nov 6, 2009 at 9:25 PM, Gottlob Frege <gottlobfrege@gmail.com>wrote:
On Fri, Nov 6, 2009 at 5:13 PM, Beman Dawes <bdawes@acm.org> wrote:
On Fri, Nov 6, 2009 at 1:17 PM, Emil Dotchevski <emildotchevski@gmail.com> wrote:
On Fri, Nov 6, 2009 at 9:44 AM, Zachary Turner <divisortheory@gmail.com> wrote:
Is there anything that can be done to improve the error messages generated by the compiler when a copy fails to be made due to a boost::noncopyable?
Easy cure is to spell out the private declarations for the copy constructor and the assignment operator "by hand". We all know that this spells "non-copyable".
Because of C++0x deleted functions, the idiom for noncopyable is going to change. [...]
Interesting stuff, however... I'm not sure if any of that will help the errors. I haven't tried any experiments, but It looks to me that even if the compiler tells you exactly what class is not copyable, it doesn't tell you where the attempted copy is taking place.
And I'm not sure if anything but a compiler fix will make it better.
Indeed, and this is the real problem and the reason I mentioned it would probably involve catering to the compiler and be highly compiler specific, albeit extremely useful. There are always ways to finesse error messages or do tricky things just to get the compiler to report a different error message. In this case the goal would be to make the compiler fail in such a way as to report the class the actual copy was taking place in. I'm also not sure if it's possible, but if it were it would be pretty useful.
participants (4)
-
Beman Dawes
-
Emil Dotchevski
-
Gottlob Frege
-
Zachary Turner