Author Topic: VC9 + _SECURE_SCL  (Read 13870 times)

duplexius

  • Not-a-newbie
  • *
  • Posts: 25
  • Karma: 3
    • View Profile
VC9 + _SECURE_SCL
« on: October 15, 2008, 03:05:12 AM »
Hello everyone,

this is a tip for everyone working with VS2005 or VS2008.
Since VS2005 Microsoft has implemented so called secure scl functionality, providing security checks for containers such as std::vector, std::set and so on. By default it's turned on (_SECURE_SCL=1).

Now, if you turn that setting off by defining _SECURE_SCL=0 (for example directly in one of your projects), you must make sure that all libraries linked have the same setting. This is because the container representations are different. If you mix up the two settings, you will result in weird access violation errors, which seem to make no sense at first.

In one of our projects we had to turn it off and ran into these problems. Either have the setting on or off throughout all your libraries. This includes RakNet.

The same applies for _HAS_ITERATOR_DEBUGGING=0 in debug builds.


Hope this helps you guys.

More details can be found at:
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=352699

Rak'kar

  • Administrator
  • Hero Member
  • *****
  • Posts: 6895
  • Karma: 291
    • View Profile
    • RakNet
Re: VC9 + _SECURE_SCL
« Reply #1 on: October 15, 2008, 10:58:58 AM »
Thanks, what kind of problems did you see?

OvermindDL1

  • Anti-Spam Moderator
  • Hero Member
  • ****
  • Posts: 855
  • Karma: 40
  • Programmer
    • View Profile
    • OvermindDL1's Site
Re: VC9 + _SECURE_SCL
« Reply #2 on: October 15, 2008, 11:50:59 AM »
Oh it adds crap like bounds checking (this is C++ after all, not Java, freakin retards...) and such things that do things like, for example, slow down my grammar parsing by over 1000x (yes it takes over 1000x longer to parse my grammar with that _SECURE_SCL=1 rather then _SECURE_SCL=0, *very* irritating, I just always turn it off in all my projects as I know I do bounds checking correctly and myself, you know testing an iterator with the end() and so forth).  Quite literally though, in my grammar it even turned one code section from 4 lines of assembly in release mode that ran nice and fast to over 50 lines with about 20 function calls to the bounds checking function in it, that was horrible...

I just kind of assumed everyone set _SECURE_SCL=0 in their preprocessor properties, who would want it on at all?  Along with all of the other Microsoft crap SECURE macros that slow everything down and add no benefit and plenty of hurt for people who actually know how to program.

duplexius

  • Not-a-newbie
  • *
  • Posts: 25
  • Karma: 3
    • View Profile
Re: VC9 + _SECURE_SCL
« Reply #3 on: October 16, 2008, 02:08:20 AM »
Rakkar:
The problems if you mix up 2 projects with different settings are access violation exceptions mostly. This is because the code per DLL is different, even if the same types are being used. ;-) This can be real pain if you don't know about _SECURE_SCL in the first place.

Regarding performance drain, I think it's not always as dramatic as 1000x. Microsoft says that the performance drop should be minor only. I guess it's not, then.

OvermindDL1

  • Anti-Spam Moderator
  • Hero Member
  • ****
  • Posts: 855
  • Karma: 40
  • Programmer
    • View Profile
    • OvermindDL1's Site
Re: VC9 + _SECURE_SCL
« Reply #4 on: October 16, 2008, 03:36:58 AM »
Yes, Microsoft really screwed up on their compiler this way.  Look at the CRT, you cannot even link modules that use different CRTs, but you can link (and they *will* horribly crash) modules with different _SECURE_SCL definitions as the linker is not aware of it.

I am just always in this habit of always adding this to my preprocessor definitions in any project I create or download, might be useful for everyone here to keep your code more like C++ and not Microsoft variation of it, not to mention the programs are *always* faster with these defined (just add them to the end of your current preprocessor definitions):
;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0;_SCL_SECURE_NO_DEPRECATE;_HAS_ITERATOR_DEBUGGING=0

If you use and of the compiled libraries in boost, just add this to your bjam command-line:
define=_CRT_NONSTDC_NO_DEPRECATE define=_CRT_SECURE_NO_DEPRECATE define=_SECURE_SCL=0 define=_SCL_SECURE_NO_DEPRECATE define=_HAS_ITERATOR_DEBUGGING=0

So on and so forth, quite useful, just make sure that *everything* you build that uses the STL library is compiled with these (C apps, apps that do not use the STL, etc..., do not need it, but good to add it nonetheless).

And no, it is not anywhere near 1000x normally, just my parser uses a lot of iterators that should normally compile mostly out, but the freaking compiler adds in all that crap and does not remove it when it optimizes out the iterators, so I practically had half the parser source code just being calls to the range bounds checking function, really really retarded.  I still wish the person who decided to add that (and make it default on for some god forsaken reason) would get flogged for a year straight, I lost so much time/sanity because of him/them, now I have to edit every freaking project I create or download to add the above line in every projects configuration file just to keep some sanity in speed in some of my code.

Yes, if you cannot tell, I am still highly irritated by their stupidity of a decision.  If I wanted bounds checking, I would use Java or .NET or something, not C++...

EDIT:  If you want to know how the ABI changes, with _SECURE_SCL=0 an iterator size is 4 bytes (8 on 64-bit), a single pointer.  With _SECURE_SCL=1 it is double that, so 8 bytes (16 on 64-bit) because it keeps a pointer to its parent container, thus that changes the storage sizes of everything that uses them, hence why you cannot link in code using different _SECURE_SCL settings, and the real kicker, the linker DOES NOT CATCH IT.

It does other things too, if it is _SECURE_SCL=1 it dereferences the pointer to the parent object, gets its beginning and end, and compares the current iterator position to those to make sure it is bounded within, this does not break the linking though, this would work fine if you could choose it on a per file or per usage basis (whoever decided to force normal stl containers to use that style is a retard, if they wanted it they should have made new-named secure versions in their stdext namespace, like they do other things).  But yes, it is the fact they are different sizes with different settings, and as stated, the linker does not catch it, really screws things up.  As stated, the people who decided to implement that need to be flogged for a long extended period (there were some programmers on the team who were vocally opposed to it, too bad they were not loud enough...).  It is reasons like this which is why I stayed with VC7.1 for so long, and still would have of except a certain library I require requires a more standards conforming compiler then VC7.1 was (and VC8.0 supported, too bad it breaks other things...).
« Last Edit: October 16, 2008, 03:50:56 AM by OvermindDL1 »