I have an application that uses numerous templates and template specializations, and during MSVC compilation many messages are output showing how the templates are being compiled. This makes for an incredibly difficult time finding an actual compilation error. These messages are not output when the application is compiled on Linux using g++.
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\INCLUDE\map(382)
: see reference to function template instantiation 'std::pair<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,bool> std:
:_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,true>>::insert<std::pair<std::string,uint64_t>>(_Valty &&)' being compiled
with
[
_Kty=std::string
, _Ty=size_t
, _Pr=std::less<std::string>
, _Alloc=std::allocator<std::pair<const std::string,size_t>>
, _Valty=std::pair<std::string,uint64_t>
]
Is there a way can I suppress these more or less useless messages? Or possibly lower the verbosity setting? I've tried looking at link but I'm not sure if there is a flag that relates to the messages I'm seeing.
The message is related to an warning (or error) with a specific template instantiation. If it is a warning, you could suppress it (via #pragma warning, or project settings), and this message would also go away. Or, you could fix the cause of the warning. There is no way to suppress this message without also suppressing the warning, because without it, the warning doesn't make much sense.
Related
This question already has answers here:
C++ Boost: what's the cause of this warning?
(6 answers)
Closed 2 years ago.
I'm porting an old project from Boost 1.48 to Boost 1.61. The project is compiled using MSVC 2013. There are several reported errors during build which I think are boost related but unfortunately the bug reports are not very helpful at all.
3> entry.cpp
4>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(2715): error C2220: warning treated as error - no 'object' file generated
4>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(2715): warning C4996: 'std::_Fill_n': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
4> c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(2701) : see declaration of 'std::_Fill_n'
4> c:\boost\boost_1_61_0\boost\random\detail\polynomial.hpp(114) : see reference to function template instantiation '_OutIt std::fill_n<boost::random::detail::polynomial_ops::digit_t*,size_t,boost::random::detail::polynomial_ops::digit_t>(_OutIt,_Diff,const _Ty &)' being compiled
4> with
4> [
4> _OutIt=boost::random::detail::polynomial_ops::digit_t *
4> , _Diff=size_t
4> , _Ty=boost::random::detail::polynomial_ops::digit_t
4> ]
I cannot see anything in the above that helps me identify where the problem is, there are no line numbers and the snippet of code is not from the compiled file.
#Eljay, does it have a human readable text option I could locate in the IDE? – SPlatten 43 mins ago
The thing you posted IS human readable text. It actually describes a warning with a reference to documentation. ¯\(ツ)/¯ Maybe you can just tell the compiler you don't want to receive warnings
In addition, you can use the keywords to google additional information:
C++ Boost: what's the cause of this warning?
Many libraries in addition already have a warning-suppression header (look for e.g. boost/iostreams/detail/config/disable_warnings.hpp or boost/random/detail/disable_warnings.hpp). The fact that known benign warnings "slip through" might indicate that the library needs to update their suppressions, OR you might need to upgrade your boost version.
I'm using msvc cl.exe directly without visual studio and would like to have an easy way to read warnings and errors. I have quite complicated template setup and when i receive some warning or errors i have to scroll through wall of compiler output like
/internal/include/internal/scene/states/scene_events.h(32): error C2440: 'static_cast': cannot convert from 'game::events::random_event' to 'float'
/helpers/tsm/include/tsm/internal/actions.h(55): note: see reference to function template instantiation 'void game::internal::playing_event::receive_event::operator ()<FSM,OutState>(game::events::random_event &&,FSM &,InState &,game::internal::playing_event &) const' being compiled
with
[
FSM=tsm::back::internal::machine_base<game::internal::scene_fsm>,
OutState=game::internal::ready,
InState=game::internal::ready
]
/helpers/tsm/include/tsm/internal/actions.h(54): note: while compiling class template member function 'void tsm::actions::internal::action_invocation<Action,FSM,Event,InState,OutState>::operator ()(Event &&,FSM &,InState &,OutState &) const'
with
[
Action=game::internal::playing_event::receive_event,
FSM=tsm::back::internal::machine_base<game::internal::scene_fsm>,
Event=game::events::random_event,
InState=game::internal::ready,
OutState=game::internal::playing_event
]
....
and so on and so on. are there any options to disable "note:" output?
i didn't find any in official docs
Sorry for being the bearer of the bad news, but there is no way to disable those notes output from the compiler diagnostics.
There are (were) some filtering 3rd party tools, but discussing those would be offtopic.
I'm receiving the following warning in my project:
warning C4927: illegal conversion; more than one user-defined conversion has been implicitly applied while calling the constructor 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string(const _Elem *)'
with
[
_Elem=char
]
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xstring(778) : see declaration of 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string'
I understand why it's happening, I'm just unable to suppress it. I've tried adding it to the Disable Specific Warnings list in my project settings, and I've also set my warning level to Turn Off All Warnings (/W0), yet the warning persists. Does anyone have any recommendations on how to hide the message?
You can control Visual Studio warnings directly in code using #pragma warning (https://msdn.microsoft.com/en-us/library/2c8f766e.aspx). If you'd like to silence the warning for a single line, you can put the following immediately before the line:
#pragma warning (suppress: 4927)
line-that-causes-warning-4927
You can also disable it from any point past the #pragma, by using 'disable' instead of 'suppress'. However, as the comments suggest, it's better to actually fix the warning, because it could be causing issues in your program.
Concepts, that would render these tools unnecessary, are not part of C++11.
STLFilt would have been one option but it is no longer maintained.
Clang claims to give expressive diagnostics although important C++11 features are not available yet.
colorgcc seems to be abandoned since 1999.
What production quality tools are available to decipher error messages stemming from template-based code? Eclipse-CDT support would be nice too. :)
If I give up on C++11, what options do I have for C++98?
Related questions:
Deciphering C++ template error messages
Improving g++ output
Let's have a stab at an answer (I marked this community wiki so we get a good response together)...
I'm working since a long time with templates and error messages have generally improved in some way or another:
Writing a stack of errors creates a lot more text but also typically includes the level the user is looking at and this generally includes a hint at what the actual problem is. Given that the compiler only sees a translation unit tossed at it, there isn't a lot which can be done determining which error in the stack is the one most suitable for the user.
Using concept checkers, i.e. classes or functions which exercise all the required members of template arguments and possibly generating errors messages using static_assert() give the template author a way to tell users about assumptions which apparently don't hold.
Telling the user about types he writes rather than expanding all typedefs as the compiler like to see at the lowest level also helps. clang is rather good at this and actually gives you error messages e.g. talking about std::string rather than expanding things type to whatever it ends up to be.
A combination of the technique actually causes e.g. clang to create quite decent error message (even if it doesn't implement C++2011, yet; however, no compiler does and as far as I can tell gcc and clang are leading the pack). I know other compiler developers actively work on improving the template error messages as lots of programmers have discovered that templates actually are a huge leap forward even though the error messages are something which takes a bit of getting used to.
One problem tools like stlfilt face is that C++ compilers and libraries are under active development. This results in error messages shifting all the time, causing the tool to receive different outputs. While it is good that compiler writers work on improving error messages, it certainly makes life harder for people who try to work from the error messages they got. There is another side to this as well: once a certain error pattern is detected to be common and is picked up e.g. by stlfilt (well, it isn't actively maintained as far as I know) compiler writers are probably keen to report the errors following these patterns directly, possibly also providing additional information available to the compiler but not emitted before. Put differently, I would expect that compiler writers are quite receptive to reports from users describing common error situations and how they are best reported. The compiler writers may not encounter the errors themselves because the code they are working on is actually C (e.g. gcc is implemented in C) or because they are so used to certain template techniques that they avoid certain errors (e.g. omission of typename for dependent types).
Finally, to address the question about concrete tools: the main "tool" I'm using when I get kind of stuck with a compiler complaining about some template instantiation is to use different compilers! Although it isn't always the case but often one compiler reports an entirely incomprehensible error messages which only makes sense after seeing the fairly concise report from another compiler (in case you are interested, I regularly use recent version of gcc, clang, and EDG for this). I'm not aware of a readily packaged too like stlfilt, however.
I know this may not be as helpful as you wanted, but I've found the best tool against template error messages is knowledge.
A good understanding of the STL and how to use it will help you avoid lots of errors in the first place. Secondly, often error messages refer to functions in the STL source - if you have a rough idea how the STL is implemented, this can be extremely helpful in deciphering what the error message is going on about. Finally, compiler makers are aware of this issue and are gradually improving error message output, so you would do well to stick to the latest version of your compiler.
Here's a good example of an obscure template error:
std::vector<std::unique_ptr<int>> foo;
std::vector<std::unique_ptr<int>> bar = foo;
unique_ptr is not copyable, it can only be moved. So trying to assign a vector of unique_ptr to another vector will mean somewhere in the vector source code will try to copy a unique pointer. Therefore the error will originate from code which is not yours and throw a fairly opaque error message as a result. The ideal error message would be
main.cpp(20): cannot construct 'bar' from 'foo': foo's template type is non-copyable
Instead, VS2010 gives the following error:
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xmemory(48): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
1> with
1> [
1> _Ty=int
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\memory(2347) : see declaration of 'std::unique_ptr<_Ty>::unique_ptr'
1> with
1> [
1> _Ty=int
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xmemory(197) : see reference to function template instantiation 'void std::_Construct<std::unique_ptr<_Ty>,const std::unique_ptr<_Ty>&>(_Ty1 *,_Ty2)' being compiled
1> with
1> [
1> _Ty=int,
1> _Ty1=std::unique_ptr<int>,
1> _Ty2=const std::unique_ptr<int> &
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xmemory(196) : while compiling class template member function 'void std::allocator<_Ty>::construct(std::unique_ptr<int> *,const _Ty &)'
1> with
1> [
1> _Ty=std::unique_ptr<int>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\vector(421) : see reference to class template instantiation 'std::allocator<_Ty>' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<int>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\vector(481) : see reference to class template instantiation 'std::_Vector_val<_Ty,_Alloc>' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<int>,
1> _Alloc=std::allocator<std::unique_ptr<int>>
1> ]
1> main.cpp(19) : see reference to class template instantiation 'std::vector<_Ty>' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<int>
1> ]
Sifting through this there are clues. The first section references a private member access of std::unique_ptr<int>. The second section, if you click through to the source line, points at the copy constructor of unique_ptr, which is declared beneath a private: specifier. So now we know we tried to copy a unique_ptr which is not allowed. Sections 3, 4 and 5 just point to boilerplate code - it's just noise. Section 6 says "see reference to class template instantiation 'std::_Vector_val<_Ty,_Alloc>' being compiled". In other words, this error happened in vector's template code. The last section is most interesting: it directly points at the line declaring foo in your own source code - it's figured out where in your own source code the error originated from!
So adding up the clues:
It originates in foo,
It originates in vector code,
It tries to copy a unique_ptr which is not allowed.
Conclusion: the vector tried to copy one of its elements, which is not allowed. Review code for foo and check for anything causing a copy.
Since the compiler only pointed at foo's declaration, if the assignment is far away in the source code some hunting will be involved. This obviously is not ideal, but I think this approach ultimately gives you more chance of fixing mistakes in general. You'll start to recognise that kind of error dump means "you copied a unique_ptr". Again, I'm not defending it, it definitely needs improving - but I think these days there's just enough information in the output that combined with a good knowledge of the STL allows you to fix the problem.
I have found Clang to generate the best error messages for heavily templated code.
Of course verbosity is unavoidable in most cases, but it's still better than GCC or MSVC most of the time. Here's the Clang error message for the example code posted by AshleysBrain:
$ clang++ -std=c++11 -stdlib=libc++ -o dummy dummy.cpp
In file included from dummy.cpp:1:
In file included from /usr/include/c++/v1/vector:243:
In file included from /usr/include/c++/v1/__bit_reference:15:
In file included from /usr/include/c++/v1/algorithm:594:
/usr/include/c++/v1/memory:1425:36: error: calling a private constructor of class 'std::__1::unique_ptr<int,
std::__1::default_delete<int> >'
::new ((void*)__p) _Tp(_STD::forward<_Args>(__args)...);
^
/usr/include/c++/v1/memory:1358:14: note: in instantiation of function template specialization
'std::__1::allocator_traits<std::__1::allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > >
>::__construct<std::__1::unique_ptr<int, std::__1::default_delete<int> >, std::__1::unique_ptr<int,
std::__1::default_delete<int> > &>' requested here
{__construct(__has_construct<allocator_type, pointer, _Args...>(),
^
/usr/include/c++/v1/vector:781:25: note: in instantiation of function template specialization
'std::__1::allocator_traits<std::__1::allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > >
>::construct<std::__1::unique_ptr<int, std::__1::default_delete<int> >, std::__1::unique_ptr<int,
std::__1::default_delete<int> > &>' requested here
__alloc_traits::construct(__a, _STD::__to_raw_pointer(this->__end_), *__first);
^
/usr/include/c++/v1/vector:924:9: note: in instantiation of function template specialization
'std::__1::vector<std::__1::unique_ptr<int, std::__1::default_delete<int> >,
std::__1::allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > >
>::__construct_at_end<std::__1::unique_ptr<int, std::__1::default_delete<int> > *>' requested here
__construct_at_end(__x.__begin_, __x.__end_);
^
dummy.cpp:7:37: note: in instantiation of member function 'std::__1::vector<std::__1::unique_ptr<int,
std::__1::default_delete<int> >, std::__1::allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > >
>::vector' requested here
std::vector<unique_ptr<int>> bar = foo;
^
/usr/include/c++/v1/memory:1997:5: note: declared private here
unique_ptr(const unique_ptr&);
^
1 error generated.
It's still long and ugly, but in my opinion much clearer regarding what/where the problem is.
So the 4251 warning is a serious base of at least microsoft's compiler. Essentially, any time you use a template class or non-dllexport class anywhere in the header definition you will get this warning. Better yet, there are numerous classes in stl (like map) where you can't even get rid of this error, period.
My problem is, is that for a specific class, the "#pragma warning(disable: 4251)" just flat out isn't working. It is working everywhere else but here.
DelWestInspectionProgram.cpp
#include "stdafx.h"
#pragma warning(disable: 4251)
...
Output Log:
E:\svn\VisionNow\VisionSuite\VI.Inspector.ImageProcessing.Common\BIImage.h(79): warning C4251: 'BIImage::_data' : class 'boost::shared_array<T>' needs to have dll-interface to be used by clients of class 'BIImage'
6> with
6> [
6> T=unsigned char
6> ]
6>E:\svn\VisionNow\VisionSuite\VI.Inspector.ImageProcessing.Operators\BIImageOperator.h(25): warning C4251: 'BIImageOperator::_savePath' : class 'std::basic_string<_Elem,_Traits,_Ax>' needs to have dll-interface to be used by clients of class 'BIImageOperator'
6> with
6> [
6> _Elem=char,
6> _Traits=std::char_traits<char>,
6> _Ax=std::allocator<char>
6> ]
Any help would be greatly appreciated.
From my own experience there are two issues: when it is a DLL import and when it is a DLL export.
Where it is the dllexport, Microsoft seems to ignore the #pragma warning but this is just the one project so easy to put into the compiler settings to ignore this warning. I found if you put it there, Microsoft does not issue the warning.
Where it is the dllimport, i.e. the file using your header. I found there Microsoft does not ignore the pragma and does not issue the warning, so putting it in both places will fix your issue.
My guess is that the 79 projects that suppress the warning fine are those ones that are not the DLL itself.
The warning is probably there for a reason, that being that if your client library is using a different version of boost, or even a different compiler setting, it might break.
As far as I know, some errors cannot be disabled. It is that way with the Linker. Therefore I would assume it is the same way with some compiler too. But in general I would put it inside your stdafx.h file, or at least before it. Putting it after doesn't guarantee anything, especially since we can't see your code.
[EDIT]
On the other hand that is a serious warning that I would fix if I were you and not just ignore it. If you search here on stack overflow you will find some great discussions about why it is a problem.