Home > Articles > Programming > C/C++

C++ Reference Guide

Hosted by

Visual C++ 8.0 Hijacks the C++ Standard, Part I

Last updated Jan 1, 2003.

A heated debate has been raging in the past couple of weeks on the C++ standards committee's reflectors (mailing lists). The source of this controversy is Microsoft's Visual C++ 8.0 compiler. The compiler itself is unarguably good. However, its designers seem to have stepped out of their jurisdiction, turning it into a creative means of (mis)interpreting and propertizing the C++ standard.

The Essence of the Controversy

A line of code is worth a thousand words. Consider the following std::copy() call:

void vec_copy(const std::vector<char> & vc, std::vector<char> &vc2)
 std::copy(vc.begin(), vc.end(), std::back_inserter(vc2));

This is fully-compliant and well-behaved code. When you compile this function with Visual Studio 2005 Beta 2 (which uses the Visual C++ 8.0 compiler), everything's jolly. Now change the std::copy() call slightly to:

char dest[10]={0};
char source[]="test";
std::copy(source, source + 5, dest);

This is a perfectly valid std::copy() call. Is this code safe? Yes, it is. The buffer to which the string is copied is large enough, it's properly initialized, and the source sequence contains precisely 5 characters (the four letters of the string "test" and a terminating null).

Compile this call under Visual C++ 8.0 using the default settings and behold: you get a compilation warning! If that's not shocking enough, wait until you see what this cheeky warning actually says:

warning C4996: 'std::_Copy_opt' was declared deprecated
    c:\program files\microsoft visual studio 8\vc\include\xutility(1837) : see declaration of 'std::_Copy_opt'
    c:\documents and settings\dani\my documents\visual studio 2005\projects\general proj\general proj.cpp(12) : see reference to function template instantiation '_OutIt std::copy<char*,char*>(_InIt,_InIt,_OutIt)' being compiled
      _OutIt=char *,
      _InIt=char *

Look at the first line of this verbose harangue. First of all, did I call a function called std::_Copy_opt()? No, I didn't. While it's perfectly legal to delegate standard algorithm calls to implementation-defined specializations, Joe coder (and yours truly) would appreciate a more-to-the-point warning message, especially when the code in question has absolutely nothing amiss.

Admittedly, beta compilers sometimes do foolish things, especially when their writers are imbued with too many good intentions. But you know me well enough to suspect that that's not why I'm dedicating a column to this warning, don't you? What's really irritating here is something else. Read the first line again:

'std::_Copy_opt' was declared deprecated [italics mine, DK]

"For God's sake, when did the standards committee deprecate a standard algorithm? Why on earth would these brilliant committee members do such a stupid thing? And how come I've never heard about it?" some of you are probably asking, with reason. Breathe easy. The standards committee hasn't deprecated std::copy(), nor has such a proposal ever been made. So what's really going on here?

Plain and simple, Microsoft took the liberty to be a standards committee on its own behalf, declaring a standard algorithm (and a plethora of other standard functions and algorithms) as deprecated. Not only is this a miserable choice of words, it's also a dangerous and harmful decision.

What's in a "Deprecated Feature"?

As I explained elsewhere, a "deprecated feature" in standardese has a precise definition. Annex 4 of the Standard defines "deprecated" as: "normative for the current edition of the Standard, but not guaranteed to be part of the Standard in future revisions." In other words, when the standards committee deprecates something, it expresses the wish that this feature would go away.

Normally, this is done under two conditions:

  • The feature in questions incurs serious security, performance, or readability problems.
  • The standard prescribes a superior coding norm that is meant to replace the deprecated feature.

Let's look at a few concrete examples. The C++ standard deprecates the use of static to enforce internal linkage. There are two reasons for this. First, the static keyword is already overloaded with different meanings in different contexts. Secondly, certain implementations simply can't fulfill the internal linkage guarantee.

Another example: the use of non-const char arrays to store quoted literals is deprecated because it might suggest that the array is mutable, which it isn't:

char message[] = "hello"; //deprecated; const qualifier is missing

Likewise, the omission of an explicit return type in a function declaration (implying a return type of int) is also deprecated because readers and compilers alike aren't expected to guess what the implied return type is, nor is there any reason to treat int as a special case.

As previously stated, when the Standard deprecates a feature, it also prescribes a recommended replacement. In the case of file scope statics, unnamed namespaces are the prescribed alternative. In the case of quoted literal strings, the standard requires that the array shall be explicitly declared const, and so on.

An Innocent Mistake?

The std::copy() call in question meets neither of these criteria. It isn't necessarily more dangerous than a std::copy() call that takes iterators, nor does the Standard prescribe an allegedly superior alternative to it. Most importantly, only the standards committee has the license to deprecate a standard feature.

I'm not splitting hairs here. C++ isn't owned by Microsoft. By deprecating a standard C++ construct (whether justifiably or not -- I'll get to that in the second part) Microsoft stepped out of its jurisdiction, propertizing a programming language that they don't own.

You might argue that this was an innocent, bona fide mistake. I would have loved to believe that, too. However, a few weeks ago I received the following e-mail message. Seemingly, it has nothing to do with the topic in question:

I was participating in a thread on CodeGuru and one of the members (for whom I have a lot of respect) said:

"The 'managed extensions' for C++ have been a temporary solution for writing managed code with C++. They have become obsolete with C++/CLI, which is [emphasis in the original text, DK] part of the standard."

Is it that true that CLI is part of the C++ Standard?

Can you see what's happening here? Microsoft seems to have developed a new strategy. Instead of deliberately deviating from the standards (a policy known as "embrace and extend"), they mislead users into believing that their proprietary frameworks and tools are the standard! I know the C++ standard well enough to testify that it doesn't mention CLI not even once, and I'm willing to bet that neither will C++0x.

There's absolutely nothing about CLI that warrants its enshrinement in the text of the C++ standard -- however important and benevolent it might be -- just as you don't expect to find Java's JNI, the IPA phonetic chart, or my gold coin collection in the C++ standard. I find it hard to believe that the said member (whose name I don't know) doesn't really know the facts. I also find it hard to believe that Visual C++ 8.0 writers don't know that the adjective "deprecated" has a special meaning in the C++ standard, which is certainly incompatible with their creative and misleading usage of this term.

In the next part of this discussion, I will address the alleged security risks that this unwarranted, wholesale deprecation is allegedly meant to avert and explain why this is a very dangerous path.