In what ways is MSVC not standards-compilant? - c++

I read that MSVC is not fully compilant to the ISO C++ standard (German Wikipedia and several Tech sites).
In which ways isn't C++ standards compilant?

Actually no compiler is fully standard compliant, but MSVC gained its reputation for implementing everything that the standard didn't explicitly state in a profoundly stupid and unportable way.
I would say that the latest releases are relatively good when it comes to standard support, at least when you try to compile standard compliant code in MSVC.
But MSVC is still very lazy when it comes to pointing out code, that doesn't follow C++ standard (even on the strictest settings), so porting code from MSVC to anything else is always huge pain.
But there are still many flaws/bugs/etc... for example unlike GCC, MSVC will allow you to modify a set/map iterator.

Well, I think it depends on your definition of compliant. There are several things that have not been implemented in the standard by almost any compiler company (several suggestion from the 98ish revision and template definitions in implementation files). MS has extended the language somewhat also. However, if you write code in basic c++ without the MS extensions or libraries, it will most likely be portable to another compiler with very, very minimal work (if any).

It's been a while since I've looked into this, but the C++ library that I work on uses quite a lot of template metaprogramming (nothing horribly complicated, but still beyond the simplest levels), and for quite a while it wouldn't compile under MSVC due to bugs or missing functionality in their template resolution code, although it works fine in GCC and Intel's C++ compiler.
I don't think we've tried it in the latest couple of revisions of MSVC, so they may have fixed those bugs.
Also, IIRC, MSVC does not turn on run-time type information support by default (for performance reasons), and support for that is required by the C++ standard.

Related

C++ Standard Library Portability

I work on large scale, multi platform, real time networked applications. The projects I work on lack any real use of containers or the Standard Library in general, no smart pointers or really any "modern" C++ language features. Lots of raw dynamically allocated arrays are common place.
I would very much like to start using the Standard Library and some of the C++11 spec, however, there are many people also working on my projects that are against because "STL / C++11 isn't as portable, we take a risk using it". We do run software on a wide variety of embedded systems as well as fully fledged Ubuntu/Windows/Mac OS systems.
So, to my question; what are the actual issues of portability with concern to the Standard Library and C++11? Is it just a case of having g++ past a certain version? Are there some platforms that have no support? Are compiled libraries required and if so, are they difficult to obtain/compile? Has anyone had serious issues being burnt by non-portable pure C++?
Library support for the new C++11 Standard is pretty complete for either Visual C++ 2012, gcc >= 4.7 and Clang >= 3.1, apart from some concurrency stuff. Compiler support for all the individual language features is another matter. See this link for an up to date overview of supported C++11 features.
For an in-depth analysis of C++ in an embedded/real-time environment, Scott Meyers's presentation materials are really great. It discusses costs of virtual functions, exception handling and templates, and much more. In particular, you might want to look at his analysis of C++ features such as heap allocations, runtime type information and exceptions, which have indeterminate worst-case timing guarantees, which matter for real-time systems.
It's those kind of issues and not portability that should be your major concern (if you care about your granny's pacemaker...)
Any compiler for C++ should support some version of the standard library. The standard library is part of C++. Not supporting it means the compiler is not a C++ compiler. I would be very surprised if any of the compilers you're using at the moment don't portably support the C++03 standard library, so there's no excuse there. Of course, the compiler will have to be have been updated since 2003, but unless you're compiling for some archaic system that is only supported by an archaic compiler, you'll have no problems.
As for C++11, support is pretty good at the moment. Both GCC and MSVC have a large portion of the C++11 standard library supported already. Again, if you're using the latest versions of these compilers and they support the systems you want to compile for, then there's no reason you can't use the subset of the C++11 standard library that they support - which is almost all of it.
C++ without the standard library just isn't C++. The language and library features go hand in hand.
There are lists of supported C++11 library features for GCC's libstdc++ and MSVC 2012. I can't find anything similar for LLVM's libc++, but they do have a clang c++11 support page.
The people you are talking to are confusing several different
issues. C++11 isn't really portable today. I don't think any
compiler supports it 100% (although I could be wrong); you can
get away with using large parts of it if (and only if) you limit
yourself to the most recent compilers on two or three platforms
(Windows and Linux, and probably Apple). While these are the
most visible platforms, they represent but a small part of all
machines. (If you're working on large scale networked
applications, Solaris will probably be important, and Sun CC.
Unless Sun have greatly changed since I last worked on it, that
means that there are even parts of C++03 that you can't count
on.)
The STL is a completely different issue. It depends partially
on what you mean by the STL, but there is certainly no
portability problem today in using std::vector. locale
might be problematic on a very few compilers (it was with Sun
CC—with both the Rogue Wave and the Stlport libraries),
and some of the algorithms, but for the most part, you can
pretty much count on all of C++03.
And in the end, what are the alternatives? If you don't have
std::vector, you end up implementing something pretty much
like it. If you're really worried about the presence of
std::vector, wrap it in your own class—if ever it's not
available (highly unlikely, unless you go back with a time
machine), just reimplement it, exactly like we did in the
pre-standard days.
Use STLPort with your existing compiler, if it supports it. This is no more than a library of code, and you use other libraries without problem, right?
Every permitted implementation-defined behaviour is listed in publicly available standard draft. There is next to nothing less portable in C+11 than in C++98.

gnu c++0x backwards compatibility status - can I just switch it on and go?

I have a pretty big c++ code base (not self written).
Numerous libraries, some not so syntactically heavy, some extremely so.
Among others there's heavy use of Boost, some Eigen.
I just love some of the new features of 0x and a quick compile/test tells me that it seems all good.
This question, and this one suggest that there are some things that smell funny.
My current state is:
gcc4.4.3
libstc++6-4.4
boost-1.40
eigen 3.0 - beta3
using the std=c++0x flag.
I know the standards committee has agonized about backwards compatibility and endured serious pain.
My question is, did it work? Can I take all that code, switch on c++0x and be certain, that everything does not only compile but also work as expected?
I don't use high 0x magic, just auto and some of the usual favorites explicitly marked "implemented" on GNU C++0x status.
I would certainly recommend using GCC 4.5, as it sports more bug fixes and a more solid implementation of the latest C++0x.
With regard to the questions you linked:
This is just a type definition on a new platform. Don't worry about this, it won't really break anything or be hard to fix.
This is one of the more complicated C++0x features, but shouldn't have that much of an influence on backwards compatibility (except if boost tries to hack itself into a feature that is to become a compiler/language feature).
The only real way to check if there are problems, is to turn on the compiler flag, and see if any problems pop up. Better yet, turn on full-fledged warnings (at least on GCC, MSVC has some nagging problems in this regard) to detect as many subverted problems as possible. This isn't waterproof though. You might want to use different compilers (GCC/MSVC/Intel/Clang) to cross-check compatibility, but in the case of c++0x you'll be very limited to the common subset of the compilers you use to check. Currently I use C++0x extensively, and intend to fix any problems that come into being when the finalized standard is implemented.
There is no answer to your question, it depends on your code. Try to compile, fix compile-time problems. Once it compiles, run your test cases, and fix whatever needs to be fixed.
If you don't have test code, start there.
This cannot be answered without knowledge of the code base. In particular, with 100% backwards compatibility you might find the same issues that you can find by upgrading/changing a compiler within the same standard:
If your code is not standard, if it uses features that are specific to the compiler or version, if it has any instance of undefined behavior or depends on unspecified behaviors that just happen to work in your current platform, then if might not compile (if you are lucky) or exhibit different behavior at runtime (if you are not lucky).

What C++(98/03) features are not-so-well supported by poor compilers?

Often I read of some software cutting out some C++ features in order to be compliant with poor/old/exotic C++ compilers.
This one is just the last one I got into: Box2D isn't using namespaces because they need to support:
poor C++ compilers where namespace support can be spotty
A bigger example I can think of is Qt, which is relying upon MOC, is limiting template usage a lot and is avoiding templates (well, this is at least true for Qt3 and previous versions, Qt4 is mostly doing that to keep to their conventions).
I'm wondering what compilers are that poor?
There are lots of C++ compilers out there (I never heard of most of them), but I would hope that all of them are supporting most common(/simple?) C++ features like namespaces (unless they're dead); isn't this the case?
What are the most unsupported features?
I can easily expect the lack of external templates, maybe template partial specialization and similar features. At most even RTTI or exceptions, but I would have never suspected of namespaces.
In my experience, people are just scared of new things and especially things that broke on them once, 20 decades ago. There's no valid reason against using namespaces in anything written during this century.
If you're looking for things to toss out though, if you happened to be targeting windows not too long ago you had to do more than just toss features out of C++ and not use them, you had to use different syntax. Templates come to mind as one of the worse supported features in VC. They've gotten much better but still fail sometimes.
Another one that is not supported by that particular compiler (STILL!) is overloading virtual functions to return derived type pointers to the types the base version returned when using MI. VC just plain freaks out and you end up having to do virtual_xxx() and providing non-virtual "xxx()" functions to replicate the standard behavior.
What are the most unsupported features?
Let's abstract away export, which, sadly, was an experiment that failed. Then, by count of compiler users this is probably two-phase lookup, which Visual C++ still doesn't properly implement. And VC has a lot of users.
Basically anything that was added as part of the standardization process in C++98. That is:
Templates (Not just partial specialization -- I mean all templates)
Exceptions (Often because this one requires runtime support/overhead -- they're often not available on things like microcontrollers)
Namespaces
RTTI
If you go even older, you can add
Most everything in the standard library.
Several old compilers are just plain bad; OTOH I would strongly not recommend worrying about them. There are already several good and freely available reasonably standards compliant compilers available for pretty much every platform of which I am aware (mostly via G++).
Namespaces have been around forever. Some of the darker places in templates, maybe. But namespaces? No way. Even with templates, the vast, vast majority of usage scenarios are fine. Some compilers aren't perfect (they're software), but flat out not supporting a C++03 feature that isn't export? That just doesn't happen. Most compilers extend the language, not reduce it, and are moving to support C++0x.
RTTI and exceptions are often accused of poorly efficient implementations, but not poor implementation conformance.
If you are programming in the main stream with a main stream compiler then usually you find everything in the C++03 standard supported (except export as mentioned by sbi (but then again nobody used the feature (as it was not supported)). The further from the main stream the compiler is the less features usually (but they are all moving forward (some more slowly than others))
Its only when you get to less used hardware that has its own proprietary compiler that support for features start to dwindle.
The main example would be mobile devices and their associated compilers (though because of their popularity in the main stream in recent years these compilers are getting updated more quickly than before).
A secondary example would by SOC devices. There compilers are so specific that they are usually in house compilers and only get as much work on them as the SOC company can afford and as a result tend to lag a long way (or at least further) behind other compilers.
Value Initialization (C++03 feature) is not properly implemented in MSVC++.
Qt doesn't use templates much because it is older than templates.

How important is standards-compliance?

For a language like C++ the existence of a standard is a must. And good compilers try their best (well, most of the good compilers, at least) to comply. Many compilers have language extensions, some of which are allowed by the standard, some of which are not. Of the latter kind 2 examples:
gcc's typeof
microsoft's compilers allow a pure virtual function declaration to have both a pure-specifier(=0) and a definition (which is prohibited by the standard - let's not discuss why, that's another topic:)
(there are many other examples)
Both examples are useful in the following sense: example1 is a very useful feature which will be available in c++0x under a different name. example2 is also useful, and microsoft has decided not to respect the ban that made no sense.
And I am grateful that compilers provide language extensions that help us developers in our routine. But here's a question: shouldn't there be an option which, when set, mandates that the compiler be as standards compliant as it can, no matter whether they agree with the standard or not. For example visual studio has such an option, which is called disable language extensions. But hey, they still allow example2.
I want everyone to understand my question correctly. It is a GREAT thing that MSVC allows example2, and I would very much like that feature to be in the standard. It doesn't break any compliant code, it does nothing bad. It just isn't standard.
Would you like that microsoft disable example2 when disable language extensions is set to true? Note that the words microsoft, example2, etc. are placeholders :)
Why?
Again, just to make sure. The crucial point is: Should a compiler bother to provide a compliant version (optionally set in the settings)(in its limits, e.g. I am not talking about export) for a certain feature when they provide a better alternative that is not standard and is perhaps even a superset of the standard, thus not breaking anything.
Standards compliance is important for the fundamental reason that it makes your code easier to maintain. This manifests in a number of ways:
Porting from one version of a compiler to another. I once had to post a 1.2 million-LOC app from VC6 to VC9. VC6 was notorious for being horribly non-Compliant, even when it was new. It allowed non-compliant code even on the highest warning levels that the new compiler rejected at the lowest. If the code had been written in a more compliant way in the first place, this project wouldn't (shouldn't)have taken 3 months.
Porting from one platform to another. As you say, the current MS compilers have language extensions. Some of these are shared by compilers on other platforms, some are not. Even if they are shared, the behavior may be subtly different. Writing compliant code, rather that using these extensions, makes your code correct from the word go. "Porting" becomes simply pulling the tree down and doing a rebuild, rather than digging through the bowels of your app trying to figure out why 3 bits are wrong.
C++ is defined by the standard. The extensions used by compilers changes the language. New programmers coming online who know C++ but not the dialect your compiler uses will get up to speed more quickly if you write to Standard C++, rather than the dialect that your compiler supports.
First, a reply to several comments. The MS VC extension in question is like this:
struct extension {
virtual void func() = 0 { /* function body here */ }
};
The standard allows you to implement the pure virtual function, but not "in place" like this, so you have to write it something like this instead:
struct standard {
virtual void func() = 0;
};
void standard::func() { ; }
As to the original question, yes, I think it's a good idea for the compiler to have a mode in which it follows (and enforces) the standard as accurately as possible. While most compilers have that, the result isn't necessarily as accurate a representation of the standard as you/I would like.
At least IMO, about the only answer to this is for people who care about portability to have (and use) at least a couple of compilers on a regular basis. For C++, one of those should be based on the EDG front-end; I believe it has substantially better conformance than most of the others. If you're using Intel's compiler on a regular basis anyway, that's fine. Otherwise, I'd recommend getting a copy of Comeau C++; it's only $50, and it's the closest thing to a "reference" available. You can also use Comeau online, but if you use it on a regular basis, it's worth getting a copy of your own.
Not to sound like an EDG or Comeau shill or anything, but even if you don't care much about portability, I'd recommend getting a copy anyway -- it generally produces excellent error messages. Its clean, clear error messages (all by themselves) have saved enough time over the years to pay for the compiler several times over.
Edit: Looking at this again, some of the advice is looking pretty dated, especially the recommendation for EDG/Comeau. In the three years since I originally wrote this, Clang has progressed from purely experimental to being quite reasonable for production use. Likewise, the gcc maintainers have (IMO) made great strides in conformance as well.
During the same time, Comeau hasn't released a single new version of their compiler, and there's been a new release of the C++ standard. As a result, Comeau is now fairly out of date with respect to the current standard (and the situation seems to be getting worse, not better -- the committee has already approved a committee draft of a new standard that is likely to become C++14).
As such, although I recommended Comeau at that time, I'd have difficulty (at best) doing so today. Fortunately, most of the advantages it provided are now available in more mainstream compilers -- both Clang and gcc have improved compliance (substantially) as outlined above, and their error messages have improved considerably as well (Clang has placed a strong emphasis on better error messages, almost from its inception).
Bottom line: I'd still recommend having at least two compilers installed and available, but today I'd probably choose different compilers than I did when I originally wrote this answer.
"Not breaking anything" is such a slippery slope in the long run, that it's better to avoid it altogether. My company's main product outlived several generations of compilers (first written in 1991, with RW), and combing through compiler extensions and quiet standards violations whenever it was the time to migrate to a newer dev system took a lot of effort.
But as long as there's an option to turn off or at least warn about 'non-standard extension', I'm good with it.
34, 70, 6.
I would certainly want an option that disables language extensions to disable all language extensions. Why?
All options should do what they say they do.
Some people need to develop portable code, requiring a compiler that only accepts the standard form of the language.
"Better" is a subjective word. Language extensions are useful for some developers, but make things more difficult for others.
I think that it's critical that a compiler provide a standards-only mode if it wants to be the primary one used while developing. All compilers should, of course, compile standards compliant code, but it's not critical they they don't extend if they don't think of themselves as the primary compiler -- for example, a cross-compiler, or a compiler for a less popular platform that is nearly always ported to, rather than targeted.
Extensions are fine for any compiler, but it would be nice if I had to turn them on if I want them. By default, I'd prefer a standards-only compiler.
So, given that, I expect MSVC to be standards-only by default. The same with gcc++.
Stats: 40, 90, 15
I think standards compliance is very important.
I always consider source code is more for the human readers than for the machine(s). So, to communicate programmer's intention to the reader, abiding the standard is like speaking a language of lowest common denominator.
Both at home and work, I use g++, and I have aliased it with the following flags for strict standard compliance.
-Wall -Wextra -ansi -pedantic -std=c++98
Check out this page on Strict ANSI/ISO
I am not a standards expert, but this has served me well. I have written STL-style container libraries which run as-is on different platforms, e.g. 32-bit linux, 64-bit linux, 32-bit solaris, and 32-bit embedded OSE.
Consider indicators on cars (known as "turn signals" in some jurisdictions); they are a reliable way to determine which direction someone's going to turn off a roundabout... until just one person doesn't use them at all. Then the whole system breaks down.
It didn't "hurt anyone" or obviously "break anything" in IE when they allowed document.someId to be used as a shortcut for document.getElementById('someId').... however, it did spawn an entire generation of coders and even books that consequently thought it was okay and right, because "it works". Then, suddenly, the ten million resulting websites were entirely non-portable.
Standards are important for interoperability, and if you don't follow them then there's little point in having them at all.
Standards-compliance hounds may get hated for "pedanticism" but, really, until everybody follows suit you're going to have portability and compatibility problems for ever.
How important standards-compliance is depends on what you are trying to achieve.
If you are writing a program that will never be ported outside of its current environment (especially a program that you're not planning to develop/support for a long time) then it's not very important. Whatever works, works.
If you need your program to remain relevant for a long time, and be easily portable to different environments, than you will want it to be standards compliant, since that's the only way to (more or less) guarantee that it will work everywhere.
The trick, of course, is figuring out which situation you are actually in. It's very common to start a program thinking it is a short-term hack, and later on find that it's so useful that you're still developing/maintaining it years later. In that situation your life will be much less unpleasant if you didn't make any short-sighted design decisions at the beginning of the program's lifetime.

Differences between template class implemenations in C++ on Linux and MSVC Win32

I'm trying to port some old Linux code to run on Windows and am running into a whole bunch of compiler errors that seem to be stemming from the considerable use of template classes. Are there really any significant differences between how templates must be implemented for linux vs MSVC? If so, could someone give an overview of what's actually different? I've found lots of documentation, but nothing that actually lays down what the differences are.
The C++ language is defined by the C++ Standard - it isn't an operating system specific thing. How well the Standard is implemented varies from compiler to compiler, not from OS to OS.
Having said that, if it is very old code, you will probably find that the modern compilers on both Windows and Linux won't compile it. This is because these modern compilers are much stricter in their adherence to the C++ Standard, and chuck out code that earlier and less compliant compilers would have let slide.
Bottom line - you need to address each error on its own terms. Or possibly junk the code, if it is really, really old.
It's going to depend a lot on the versions of compilers you are using both on Windows and on Linux. So I think the only way is to go through and fix the errors one by one.