Preshing on ProgrammingPreshing on Programming

The Cost of _SECURE_SCL

_SECURE_SCL is a preprocessor definition which affects the behavior of Standard C++ Library containers, like std::vector, std::map and std::list. In Visual C++ 2005 and 2008, its default value is 1, which means it’s enabled by default in Release.

If you search the Visual C++ Include Directories for _SECURE_SCL (and _SCL_SECURE), you’ll find hundreds of conditional compilation directives. To make a long story short, the _SECURE_SCL definition is meant to protect you against programming errors like this one:

void main()
    std::vector<int> vector;
    *vector.end() = 0;

When the above program runs, it pops up the following error message:

This is arguably a Debug check. Why, then, is it enabled by default in Release? My guess is that it’s enabled for the same reason as Buffer Security Checks – to minimize security vulnerabilities. After all, “SECURE” is right there in the name. Nonetheless, Microsoft changed their mind in Visual C++ 2010, and it’s no longer enabled by default. Perhaps this kind of programming error is not a common attack vector after all. Or perhaps the risk of exploitation is already mitigated by Address Space Layout Randomization, which was introduced in Windows Vista. I’m only speculating.

To turn this feature off, you must #define _SECURE_SCL 0 before including any Standard C++ Library headers. Be careful though, because you’ll need to turn it off for every source file that uses the Standard C++ Library, including external libraries – otherwise, you’ll crash!

Performance Measurements

I tested this preprocessor definition in wordcount.exe, a benchmarking application used for Hash Table Performance Tests. I used the same testing procedure described in an earlier post, The Cost of Enabling Exception Handling, so feel free to review that post to better understand this chart:

For most tests in the benchmark suite, it has little to no effect on performance. In some cases, performance actually improves slightly. (See the end of this post for some theories about that.) In other cases, some overhead can be seen, especially in the case of stdext::hash_map, which runs about 10% slower. As you’d expect, the size of the penalty seems to depend on how many operations are performed using Standard C++ iterators. Indeed, stdext::hash_map makes heavy use of std::list iterators internally.

With that kind of performance overhead, I think it’s reasonable to consider _SECURE_SCL a performance pitfall in Visual C++ 2008. You might want to disable it in Release if you wish to maximize performance, and you’re confident you can debug without it. If you can debug C++ code at all, then you probably can.

As a closing side note, there’s a similar preprocessor definition, _HAS_ITERATOR_DEBUGGING, which is enabled by default in Debug. This definition introduces a global mutex lock, and can therefore significantly slow down the performance of Debug configurations in a multithreaded application. Something else to watch out for if you spend a lot of time debugging such applications.