_SECURE_SCL is broken in release builds - by Alan Bain

Status : 

  By Design<br /><br />
		The product team believes this item works according to its intended design.<br /><br />
		A more detailed explanation for the resolution of this particular item may have been provided in the comments section.


3
0
Sign in
to vote
ID 352699 Comments
Status Closed Workarounds
Type Bug Repros 0
Opened 6/24/2008 8:36:36 AM
Access Restriction Public

Description

_SECURE_SCL changes the size of iterators in release builds from 4 bytes (off) to 8 bytes on because it stores a reference to the containing object.  In fact this behaviour violates standard 23.1.10 (no swap invalidates any iterators referring to the elements of the containers being swapped).

The change in size can cause serious problems when linking against third party libraries which use the STL and can lead to situations where it is impossible to use STL (if you use libraryA built with _SECURE_SCL=0 and libraryB with _SECURE_SCL=1).  It is thus totally non standard compliant.  If there is reason to change the size of stl objects they should be renamed and put in a separate namespace e.g. stdexp::checkedvector.

There is no way for me as a user to check what setting was used by a third party library vendor and my reading of the standard suggest _SECURE_SCL=0 is required to be standard compliant due to the problem of swap and _SECURE_SCL=1.

VS2005 has a superb IDE, but the most important aspect of any C++ compiler is how closely is complies with the ISO standard.

As the MS ABI requires a complete rebuild of all DLLs for even a minor version change e.g RTM to SP1 due to the annoying embedded manifests this should be easy to fix without worries about backward compatibility.

Suggested fix:
Get rid of _SECURE_SCL and define extra objects in stdext providing the checked iterator behaviour.
Sign in to post a comment.
Posted by Angel Sinigersky on 9/15/2011 at 3:16 AM
Dear Mr. Lavavej,

if I understand it right, Visual Studio 2008 should now allow mixing of libraries: some compiled with _SECURE_SCL=0, and other libraries compiled with _SECURE_SCL=1. Yet in our software project we cannot confirm that this is true. Our code is compiled with _SECURE_SCL=0 for performance reasons, and as we link to a third-party library, we get "mysterious" crashes in Release-mode. It turned out that they disappear with _SECURE_SCL=1. Obviously, _SECURE_SCL is still important for the compatibility between different modules.

I am just reporting my observations, and I would be glad to read an additional comment about the issue.
Thanks!

Best Regards,
Angel Sinigersky
Posted by king.xulu on 12/4/2008 at 10:00 AM
Stephan, while I understand the noble goal of SECURE_SCL it simply does not work in practice to disable it, except in narrow circumstances in which one has control over every piece of software being combined. Even in the case of a single library where I put SECURE_SCL=0 at the top of the very first header file, I have already had problems in which my users had the gall to put some other header file before mine (in some compilation units). The result is that in practice I am forced to leave SECURE_SCL on, which noticably degrades performance if I continue to use STL classes for important performance-critical work.

So although that does not violate the letter of the standard, it does violate the spirit of the STL package which is supposed to provide all that beautiful functionality at essential zero cost. And indeed, I have found it did so admirably right up until Microsoft turned range checking on in Release mode.

Please, I'm begging you, turn this off in Release mode like HAS_ITERATOR_DEBUGGING.

Michael Sherman
Stanford
Posted by Microsoft on 7/29/2008 at 10:04 PM
Hi,

Thanks for reporting this issue. It is By Design, and VC9 (VS2008) conforms to the Standard.

> _SECURE_SCL changes the size of iterators in release
> builds from 4 bytes (off) to 8 bytes on because it
> stores a reference to the containing object.

Correct. _HAS_ITERATOR_DEBUGGING also changes the representations of containers and iterators.

> In fact this behaviour violates standard 23.1.10
> (no swap invalidates any iterators referring to
> the elements of the containers being swapped).

Correct for VC8 (VS2005). This was fixed in VC9. Now, every container (excluding string) owns an "aux object", which has a pointer back to its parent container. Iterators maintain pointers to the aux objects of their parent containers. When containers are swapped, their aux objects are also swapped, which allows their iterators to find their new locations. This preserves the Standard's guarantee that swapping containers (excluding string) is O(1), nofail, and non-iterator-invalidating.

> The change in size can cause serious problems when
> linking against third party libraries which use the
> STL and can lead to situations where it is impossible
> to use STL (if you use libraryA built with
> _SECURE_SCL=0 and libraryB with _SECURE_SCL=1).

Indeed. Therefore, third party libraries should ship source, or provide all combinations of release/debug SCL=1/0 HID=1/0 (there are six combinations).

> It is thus totally non standard compliant.

This is incorrect. The Standard doesn't say anything about this; implementations (such as VC) are free to have incompatible "modes". Release versus debug is one incompatible mode: VC will reject attempts to link /MD objects to /MDd objects. Similarly, static versus dynamic is another incompatible mode: VC will reject attempts to link /MT objects to /MD objects. SCL and HID merely introduce more incompatible modes.

> If there is reason to change the size of stl objects
> they should be renamed and put in a separate namespace
> e.g. stdexp::checkedvector.

That would prevent applications from automatically benefiting from these new features. You may debate the usefulness of _SECURE_SCL, but _HAS_ITERATOR_DEBUGGING is undeniably valuable, and inherently requires extra bookkeeping information (hence creating an incompatible mode).

> There is no way for me as a user to check what
> setting was used by a third party library vendor

Third party library vendors need to document this.

> and my reading of the standard suggest _SECURE_SCL=0
> is required to be standard compliant due to the
> problem of swap and _SECURE_SCL=1.

VC9 _SECURE_SCL=1 is conformant.

> VS2005 has a superb IDE, but the most important
> aspect of any C++ compiler is how closely is
> complies with the ISO standard.

Agreed! :-)

If you have further questions, feel free to E-mail me at stl@microsoft.com .

Stephan T. Lavavej
Visual C++ Libraries Developer
Posted by Microsoft on 6/25/2008 at 3:36 AM
Thanks for your feedback. We are escalating this bug to the product unit who works on that specific feature area. The team will review this issue and make a decision on whether they will fix it or not for the next release.

Thank you,
Visual Studio Product Team