Introduction

I started a special STL include file because I always use warning level 4 and including STL stuff flooded me with warnings. After fiddling around for a while I found out that STL itself switches on warnings. This happens in the file yvals.h. Therefore a peculiar including technique is necessary.

The purpose is to keep all warnings in the own source and disable the STL warning noise. This is done by switching off the warnings before you include the STL stuff and restore the original warning state afterwards.

Before switching off the warnings the file yvals.h must be included to activate the files include guard and avoid a further change of the warning state.

MSKB article 'BUG: C4786 Warning Is Not Disabled with #pragma Warning' (Article ID: Q167355) describes a warning that can't be disabled. This occured to me using a map. I think the article sample is using a tree with itself uses a map.

ASSERT and TRACE

Because I'm not using MFC but got acquainted with ASSERT and TRACE I added some defines to have this feature with STL. This is in no relation with the warnings but is quite handy in my opinion.

You can use it like in MFC. I extended ASSERT to quit a function in the release build when the assert is false. Therefore you can find six additional asserts like ASSERT_RETURN, ASSERT_RETURN_FALSE and ASSERT_RETURN_NULL depending on the return type of your funciton. You can even quit control structures with ASSERT_BREAK and ASSERT_CONTINUE.

Usage

I'm using a macro system to specify with STL elements to use or a STL_USING_ALL to include all objects covered. The STL include file is not complete (just the objects I use frequently) and must be extended if necessary. You don't need to declare using namespace std;. This is done at the end of the include file.

To use it in your code (I always place it the precompiled header file):

Conclusion

The disabled warnings are not complete and I'm adding new stuff with every project I do. I think this is basic approach to get along with STL and warning level 4. I appreciate suggestions and additions to get it more complete.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Comments and Discussions

using namespace std is bad in the header files. It's ok in the CPP files, because then you can deal with it on your own.

However, in the header files, anyone who directly or indirectly includes a header file with using namespace std (or any other namespace or using declaration for that matter) will inherit this declaration. This can cause to some hard-to-trace and unusual ambiguous or duplicate definition errors. While typically easy to work around in your own code, other libraries that you are using may be conflicting with std identifiers.

Unfortunately for me, I have tried exactly this and I haven't got it to work.
Bugs in VC6? My incompetence? I don't know.

What I have tried with a lot more success is that I set the warning level to 4 and include all the STL files in stdafx.h (my precompiled header). I then set the warning level for stdafx.cpp only to 3 (or 0, 1 or 2).

My reasoning being this: The files I include in my precompiled header I don't have any control of. Therefore I am not concerned about warnings since I can't modify them anyway. However, my own files I am most concerned in and I wish to compile all of them using warning level 4.

I've found this way to work quite well but I prefer to put the
pragmas right into stdafx.h. Quite possibly changing the
warning level on stdafx.cpp stops the warning on that cpp
files but they get emitted for all other files. Can't verify
this because I've started using VC.net now.

Wow, thanks for the info. I just got rid of just about every STL warning the complier was spitting out. Turns out I have a couple of type cast problems (they where buried in all of the other warnings ).

ZeePain! wrote:

This seems like one of those programs that started small, grew incrementally, building internal pressure, and finally barfed all over its source code sneakers. Or something.

Compiler Warning (level 1) C4503

'identifier' : decorated name length exceeded, name was truncated

The decorated name was longer than the maximum the compiler allows (247), and was truncated. To avoid this warning and the truncation, reduce the number of arguments or name length of identifiers used.

To avoid including something you don't need, I cooked up some code until these remains were left. This seems to make #pragma warning(disable:4786) work reliably. Any attempy to further simplify this bizarre code thwarts its effect.

You wrote:
"To use it in your code (I always place it the precompiled header file)"
I NEVER use precompiled headers because it introduces unnecessary dependencies (and more often than not cause more problems than it solves). Any file that includes stdafx.h CAN NOT BE REUSED! To solve this you could of course reuse a special stdafx.h that includes ALL FILES YOU'LL EVER NEED! No, no, no.

OK, got that off my chest
Now for the rest... May I suggest you create a single header file for each STL header you want to encapsulate. If you move the original STL headers to a "private" place (so they wont be picked up by the compiler) and name YOUR files the exact same as the originals in a place where the compiler WILL find them, you're half way there. As an example I use your wrapper of :
*** In your file :
// STL neccessary declaration for string
// warning numbers get enabled in yvals.h
#pragma warning(push)
#include
#pragma warning(disable: 4018) // signed/unsigned mismatch
#pragma warning(disable: 4100) // unreferenced formal parameter
#pragma warning(disable: 4146) // unary minus operator applied to unsigned type, result still unsigned
#pragma warning(disable: 4244) // 'conversion' conversion from 'type1' to 'type2', possible loss of data
#pragma warning(disable: 4245) // conversion from 'type1' to 'type2', signed/unsigned mismatch
#pragma warning(disable: 4511) // 'class' : copy constructor could not be generated
#pragma warning(disable: 4512) // 'class' : assignment operator could not be generated
#pragma warning(disable: 4663) // C++ language change: to explicitly specialize class template 'vector'
#pragma warning(disable: 4710) // 'function' : function not inlined
#pragma warning(disable: 4786) // identifier was truncated to 'number' characters in the debug
information
#pragma warning(disable: 4514) // unreferenced inline/local function has been removed
#pragma warning(disable: 4710) // 'function' : function not inlined
#pragma warning(disable: 4786) // identifier was truncated to 'number' characters in the debug information
#include
#pragma warning(pop)

NOTE: I moved the last #pragmas up before #include because I thought you had made a mistake.
Please note that these #pragmas are in effect for ALL code following the inclusion of this header (same for your original).
Needless to say I haven't tried this out and I make no guarantee as to the usefulness or quality of the above

You may want to disable the include-once defines and pragmas in this .h file -- this way people can include this file whenever they think of other things they want from STL. It also removes the necessity of having this include in one centralized place. Otherwise, great job though!

----------------------------------------
----I said my name wasn't important
---------------------------SlartiBartFast

Please can you explain this in more detail. As I understood it this means the file will only be compiled once and read once. What does this have to do with having the file in one centralized place, it has to live somewhere.

He means that you should remove the include guards so that someone could use, say, vector in a header file (e.g. as members of a class) without including other standard library headers like map that are used by the implementation in the .cpp file.

For instance:

// foo.h
#define STL_USING_VECTOR
#include "STL.h"

class foo
{
public:
int get();

private:
vector<int> m_vec;
}

// foo.cpp
#define STL_USING_MAP
#include "STL.h"

#include "foo.h"

int foo::get()
{
map<int,string> m;
// ...
}

Clearly, the header does not need to see map, so there's no need to waste time including and compiling that code for files that include foo.h. With the existing include guards, however, you must include map in the header (and thus in every file that includes the header).