Microsoft to C99 Developers: Use ISO C++(infoq.com)
infoq.com
Microsoft to C99 Developers: Use ISO C++
http://www.infoq.com/news/2012/05/vs_c99_support
13 comments
Do you also instruct your customers to run on Intel chips for optimal performance?
For those of you downvoting - please read http://www.agner.org/optimize/blog/read.php?i=49#49 . There is a long documented history of ICC producing suboptimal code for AMD processors. AMD currently has 19.1% market share and I am genuinely curious what people who use ICC do for that part of the market. I guess if you are selling an end to end solution or developing inhouse tools this is not a problem.
We regularly test on AMD chipsets (even really old ones). It's a matter of tweaking the optimization profiles, instead of selecting max for everything.
A very good point, as ICC is known to produce very bad code (intentionally) when run on AMD systems.
Technically, it does not produce very bad code when run on AMD systems, it produces very bad code for running on AMD systems.
It avoids using some performance instructions which it uses on the Intel build and which would work identically on AMD.
Their excuse is that they can't guarantee they would work identically on AMD and so resort to much slower un-pipelined code. It's like Ferrari testing a Porsche and only using 1st gear because they can't be sure that other gears would perform in the same way
Their excuse is that they can't guarantee they would work identically on AMD and so resort to much slower un-pipelined code. It's like Ferrari testing a Porsche and only using 1st gear because they can't be sure that other gears would perform in the same way
There is some truth to that, as it does not do all optimizations that it could; however, in my experience, even on AMD systems, ICC beats MSVC hands down.
have you guys considered mingw? It never seems like mingw gets any love in the real world.
In my experience, using Mingw in the real world is a mess.
It doesn't play nicely with MSVC++, which is a big problem because most third party libraries on Windows are built with MSVC++ and expect projects using them to be built with MSVC++.
And the only debugger usable with Mingw is raw GDB. The debug format it uses isn't compatible with MSVC++'s debugger. Sure, GDB is very powerful, but it's very difficult to use compared to MSVC++, XCode, and even the GDB front ends on Linux.
Also, there's not much of a build system with Mingw unless you're happy with hand rolled Makefiles or using MSYS. I've never had much luck running MSYS. Maybe it's improved lately, but downloading an arbitrary open source library and trying to run "./configure && make" in MSYS is a crap shoot. Unless the library author has taken steps to make it work it probably won't.
As somebody else said, if you're porting code from Linux that uses a lot of non-standard GCC extensions, GNU Make and autotools then Mingw is tolerable as long as you can develop entirely on Linux and only use MingW for porting and testing.
There are some limited cases where it's actually pretty good, though. For example, the open source version of Qt ships its own version of GCC, GNU Make, etc, and hides the details behind their Qt Creator IDE. If you're using Qt with minimal dependencies outside of Qt, it's a nice setup. Also, GHC and the Ruby "Windows dev kit" do the same thing for compiling/building language extensions.
It doesn't play nicely with MSVC++, which is a big problem because most third party libraries on Windows are built with MSVC++ and expect projects using them to be built with MSVC++.
And the only debugger usable with Mingw is raw GDB. The debug format it uses isn't compatible with MSVC++'s debugger. Sure, GDB is very powerful, but it's very difficult to use compared to MSVC++, XCode, and even the GDB front ends on Linux.
Also, there's not much of a build system with Mingw unless you're happy with hand rolled Makefiles or using MSYS. I've never had much luck running MSYS. Maybe it's improved lately, but downloading an arbitrary open source library and trying to run "./configure && make" in MSYS is a crap shoot. Unless the library author has taken steps to make it work it probably won't.
As somebody else said, if you're porting code from Linux that uses a lot of non-standard GCC extensions, GNU Make and autotools then Mingw is tolerable as long as you can develop entirely on Linux and only use MingW for porting and testing.
There are some limited cases where it's actually pretty good, though. For example, the open source version of Qt ships its own version of GCC, GNU Make, etc, and hides the details behind their Qt Creator IDE. If you're using Qt with minimal dependencies outside of Qt, it's a nice setup. Also, GHC and the Ruby "Windows dev kit" do the same thing for compiling/building language extensions.
Unlike ICC, MinGW's gcc.exe is not a drop in replacement for cl.exe. It's a separate compilation environment. The headers are different and often out of date compared to the Windows SDK. Microsoft extensions are not supported so it chokes on newer APIs like DirectX 11.
If you are a Mac or Linux weenie who just wants to port something over to Windows sure, no problem, use MinGW. But good luck getting any Visual Studio devs to rely on what is, for all intents and purposes, a second rate Win32 toolchain.
If you are a Mac or Linux weenie who just wants to port something over to Windows sure, no problem, use MinGW. But good luck getting any Visual Studio devs to rely on what is, for all intents and purposes, a second rate Win32 toolchain.
I don't know, I tried to use mingw to get hwloc to compile. That was one of the more unpleasant experiences in my dev career.
Good for Microsoft. If they think something is standardized garbage then they shouldn't have to use it.
C99 and C11 look like mutants compared to C89. Too many bad design decisions made by a group of people who weren't involved with the initial standardization. They even did the very thing the guy who _invented_ the language explicitly told their predecessors in no uncertain terms not to do, and reintroduced noalias pointers into the language [1].
[1] http://www.lysator.liu.se/c/dmr-on-noalias.html
C99 and C11 look like mutants compared to C89. Too many bad design decisions made by a group of people who weren't involved with the initial standardization. They even did the very thing the guy who _invented_ the language explicitly told their predecessors in no uncertain terms not to do, and reintroduced noalias pointers into the language [1].
[1] http://www.lysator.liu.se/c/dmr-on-noalias.html
Both C99 and C11 add many useful features to the language. I don't love all of the additions, but I use enough of them everyday to consider them a net benefit. It's still a vastly simpler and cleaner language than C++.
`noalias` was fundamentally broken, which is why it was never adopted by the committee. Instead, `restrict` was standardized, but `restrict` does not suffer from the problem that Ritchie highlights in the post you linked to.
It's also worth noting that C99 fixed some significant oversights in the C90 standard; C99 fully specified integer division for example (C90 left the behavior implementation-defined for negative arguments).
`noalias` was fundamentally broken, which is why it was never adopted by the committee. Instead, `restrict` was standardized, but `restrict` does not suffer from the problem that Ritchie highlights in the post you linked to.
It's also worth noting that C99 fixed some significant oversights in the C90 standard; C99 fully specified integer division for example (C90 left the behavior implementation-defined for negative arguments).
There are some Good Parts to C99/C11, most of them adopted from Unix and Plan 9. Not surprisingly, most of the bad parts are all inventions.
Read the link to dmr's comment again. His argument wasn't so much that noalias was specified incorrectly, it was that the whole idea of adding any kind of alias specifier to the language is against the spirit of C. I agree, and apparently so did the C++ committee. If you want to write FORTRAN, write a FORTRAN spec. Leave C alone.
Read the link to dmr's comment again. His argument wasn't so much that noalias was specified incorrectly, it was that the whole idea of adding any kind of alias specifier to the language is against the spirit of C. I agree, and apparently so did the C++ committee. If you want to write FORTRAN, write a FORTRAN spec. Leave C alone.
There might be some merit to this. If you want a language that is very portable and has a definition that is compact enough to be fully understood both by you and by programs you might write that operate on source code (static analyzers, interpreters, compilers, etc.), you are probably going to use C89/90 instead of C99 (at least that seems to be what K&R felt--and what K still feels). Otherwise, what advantages do you have in going with pure C99 over the C99 almost subset of ISO C++? Even if you don't really use any language features unique to C++, you would still get some safer library functions and better portability than you would if you limited yourself to the C99 standard.
> If you want a language that is very portable and has a definition that is compact enough to be fully understood both by you and by programs you might write that operate on source code (static analyzers, interpreters, compilers, etc.), you are probably going to use C89/90 instead of C99
C99 has some very hard-to-replicate features; most notably designated initializers. Without them, you cannot statically initialize any union member except the first. This is a significant problem for me.
C99 is mostly supported by every C compiler I am aware of except MSVC, so it would be portable if not for Microsoft.
> Even if you don't really use any language features unique to C++, you would still get some safer library functions and better portability than you would if you limited yourself to the C99 standard.
C++ is not available in the Linux kernel, it mangles names, and it's tricky to be disciplined enough to write in a C++ subset without letting C++ features creep in, especially on a multi-person project. Once you let C++ features creep in you can inadvertently end up with runtime static initializers, type_info symbols, exception unwinding code and debugging symbols, etc.
My current compromise is to compile as C99 everywhere except on MSVC, where I will compile as C++ and use C++ alternatives to features like designated initializers.
C99 has some very hard-to-replicate features; most notably designated initializers. Without them, you cannot statically initialize any union member except the first. This is a significant problem for me.
C99 is mostly supported by every C compiler I am aware of except MSVC, so it would be portable if not for Microsoft.
> Even if you don't really use any language features unique to C++, you would still get some safer library functions and better portability than you would if you limited yourself to the C99 standard.
C++ is not available in the Linux kernel, it mangles names, and it's tricky to be disciplined enough to write in a C++ subset without letting C++ features creep in, especially on a multi-person project. Once you let C++ features creep in you can inadvertently end up with runtime static initializers, type_info symbols, exception unwinding code and debugging symbols, etc.
My current compromise is to compile as C99 everywhere except on MSVC, where I will compile as C++ and use C++ alternatives to features like designated initializers.
What's the C++ alternative to designated initializers?
Constructors, I would assume, but that's not a very attractive alternative in my opinion.
With C++11, you can use constexpr constructors to guarantee that they run at compile-time and end up as flat data in the .data/.rodata section instead of run-time static initialization. Or so I'm told by the C++11 people I asked about it.
If MSVC supported C99, it would be portable enough for the three major platforms plus all the ports of GCC and any analyzers written for Clang/LLVM. What do you get versus C++? Implicit casting of void *, so you don't have to repeat yourself every time you use malloc, restrict, structure literals, faster compilation (yes, the same code compiles faster in C mode than C++ mode, at least in gcc), not having to remember slightly different rules about scoping, ...
Self-reply: That's only C99, by the way. Compared to C++11, C11 adds anonymous structs, and incompatible handling of atomics, noreturn, and even generics.
What do you typically use in C99 that you don't get in C89?
A few things I like, though not all of them are strictly needed:
long long foo; /* bigger ints on 32-bit platforms */
uint32_t bar; /* stdint.h, integers of specific bit width */
int array[n]; /* length-n array, where n is a variable */
for (int i = 0; i < n; i++) /* loop-local variable */
Also, the safer stdio functions like snprintf.Some of them are already in MSVC.
Off the top of my head, C99 features that I've used in the past couple months:
C11 features that I have used in the past few months:
- declarations mixed with statements
- declarations in `for` constructs
- hexadecimal floating-point literals and conversion specifiers
- the strtoxx( ) conversion routines
- the restrict qualifier
- the expanded math library
- designated initializers
- extended integer types
- compound literals
- // comments
- VLAs
- complex support
Note that some of these features are still not present in C++11.C11 features that I have used in the past few months:
- CMPLX macros
- anonymous structures and unions
- <stdalign.h>I miss C99 named initializers even in C++.
struct { struct y y; bool flag; } = { .flag = true };'for' loops
C++'s name mangling feels like a dealbreaker to me; it really hurts interoperability with other languages.
In general, C feels well-suited to be the language that (almost) every other language can talk to; C++ just doesn't fit that role so well.
In general, C feels well-suited to be the language that (almost) every other language can talk to; C++ just doesn't fit that role so well.
You can explicitly export functions you want available outside, disabling the name mangling (using export "C").
I'm not sure how else you think C++ could handle its goals without the name mangling: overloading and compatibility with C's linker system. If you have two overloaded "foo" functions you need to somehow designated them as separate linker symbols.
C has similar problems of its own: like what's the calling convention for the exported symbol? Do I push the arguments on the stack, and who cleans up? Do some arguments go into registered? Where does the return value go? What's the layout of a struct? All things are platform, compiler and compiler configuration dependent.
What other languages, that compile to object files or shared objects, that support the level of OO features etc. that C++ has, have a well-defined ABI?
I'm not sure how else you think C++ could handle its goals without the name mangling: overloading and compatibility with C's linker system. If you have two overloaded "foo" functions you need to somehow designated them as separate linker symbols.
C has similar problems of its own: like what's the calling convention for the exported symbol? Do I push the arguments on the stack, and who cleans up? Do some arguments go into registered? Where does the return value go? What's the layout of a struct? All things are platform, compiler and compiler configuration dependent.
What other languages, that compile to object files or shared objects, that support the level of OO features etc. that C++ has, have a well-defined ABI?
In avionics development, having a compiler certified for production use is a big (expensive) deal. Accordingly, you'll still find avionics people using C89 if for no other reason than because they certified a C89 compiler years ago and it still works.
These are my feelings too. C++ is not supposed to be object-oriented C, rather, it is supposed to be an improved C with more features, one being language support for OOP. You might as well just use C++.
Perhaps C++ is mostly a superset of C in a technical sense, but in practice, it comes with its own idioms, its own conventions, its own design patterns, and its own culture, all very distinct from those of C. There's far more to consider when selecting a programming language beyond "Does Language X have a superset of the features of Language Y?".
Plus, sometimes having fewer features is itself a feature. I would say that this is especially true when comparing the slim, minimal design of C with the "everything and the kitchen sink" approach of C++. Not that C++ is never useful in its own right, but that doesn't mean its appropriateness for a given task is always greater than or equal to that of C.
Plus, sometimes having fewer features is itself a feature. I would say that this is especially true when comparing the slim, minimal design of C with the "everything and the kitchen sink" approach of C++. Not that C++ is never useful in its own right, but that doesn't mean its appropriateness for a given task is always greater than or equal to that of C.
With C99 and C11 though, C is becoming larger and less minimal. I'm not sure that argument still applies.
> an improved C with more features
This mostly means it's incompatible with C even in the parts of the language both of them share. Completely valid and idiomatic C code will therefore not always compile if you use a C++ compiler.
This mostly means it's incompatible with C even in the parts of the language both of them share. Completely valid and idiomatic C code will therefore not always compile if you use a C++ compiler.
Microsoft already filled the world with "C++" programmers by letting/making C programmers use Visual Studio. All of a sudden they could put "C++" on their resumes, even if they were really still doing C coding. That rather muddied the waters, then. Now, C99 is undercut. what about C11?
Pelles is a very nice IDE and (LCC based) compiler with C99 & C11 support: http://www.smorgasbordet.com/pellesc/
C99 Developers to Microsoft: nope.
Microsoft to C99 developers: don't let the door hit you on your way out. All 10 of you on the Windows platform.
So why not use gcc or mingw? Is it just the IDE or are there other complications? I haven't developed natively on Windows since the Borland TurboC++ days, so I'm kind out out of the loop there.
- The VC compiler is actually really good, especially for Windows code (obviously)
- Visual Studio is a great IDE but more importantly it's what MS devs are used to. It's harder to attract good MS developers if you don't support Visual Studio
- Binary compatibility issues between stuff compiled with gcc/mingw and stuff compiled with VS (??? Someone chime in here if I'm wrong)
- Gcc/mingw setup on Windows is perceived as more complex than installing VS
- Visual Studio is a great IDE but more importantly it's what MS devs are used to. It's harder to attract good MS developers if you don't support Visual Studio
- Binary compatibility issues between stuff compiled with gcc/mingw and stuff compiled with VS (??? Someone chime in here if I'm wrong)
- Gcc/mingw setup on Windows is perceived as more complex than installing VS
>- Binary compatibility issues between stuff compiled with gcc/mingw and stuff compiled with VS (??? Someone chime in here if I'm wrong)
If you aren't using C++, everything should work fine. I've been using C binaries from VS and mingw together without problems :)
If you aren't using C++, everything should work fine. I've been using C binaries from VS and mingw together without problems :)
'C' doesn't have name mangling
Mixing C++ binaries from different compilers is much trickier
Mixing C++ binaries from different compilers is much trickier
MSVC has very powerful debugger. It is able to inspect STL collections, set conditional breakpoints, break on certain types of exceptions, watch complex expressions, view local variables by mouse hover etc. It can attach to running process, it may be closed-source process with my DLL, and I would be able to do source-level debugging for that DLL.
I usually compile outside of IDE (from command line / Far Manager) with custom build script and use MSVC only as a debugger: it has nice feature of opening EXE file as a project workspace.
We're stuck with MSVC until gcc and its Windows ports will have a decent GUI debugger.
I usually compile outside of IDE (from command line / Far Manager) with custom build script and use MSVC only as a debugger: it has nice feature of opening EXE file as a project workspace.
We're stuck with MSVC until gcc and its Windows ports will have a decent GUI debugger.
Aside from the great STL container inspection (There are claims that macros exist to make container inspection nice. There is also set prettyprint.), you can do all that in gdb. If you like IDEs you can use Eclipse and CDT, which has a frontend to gdb that works just as well as VS's debugger.
Sorry, but gdb and eclipse are crap for C/C++ development.
There is nothing you can do in MSVC that you can't do more slowly in a less-obvious manner in either gdb or eclipse.
There is nothing you can do in MSVC that you can't do more slowly in a less-obvious manner in either gdb or eclipse.
I spent five years doing C++ work in VS 6 through VS 9. I've spent a little more than a year doing C++ work with Eclipse 3.6 and what appears to be CDT 7.x. After figuring out (and changing, where needed) the default keybindings, I find that neither development nor debugging is any slower in Eclipse than it was in VS 8->9. (Don't get me started about the dog that was VS 6.) Also, there are quite a few things that stymied VS (such as "go to class definition") that CDT gets right every time.
Anecdata FTL, I guess. Note that the CDT of long ago was absolute trash. If you haven't tried it in the past couple of years, get a recent version of Eclipse and try again. It's really a good tool.
Anecdata FTL, I guess. Note that the CDT of long ago was absolute trash. If you haven't tried it in the past couple of years, get a recent version of Eclipse and try again. It's really a good tool.
I would like to, but from my experience thus far of writing a C library and using some C99'isms, then doing a bunch of work to port it to Windows: Windows developers are not satisfied with something working on Windows, they want to be able to compile it in Visual Studio or they won't use it. Don't know how generalisable this is, but all I know is that I'm forced to go back and remove any C99 from my code if I want my library to be used on Windows, despite the fact that the binaries I distribute work fine.
Well, I can't blame them for wanting to use their tools of choice, but as a developer wanting his work to be compatible with the most popular platform, it's an unfortunate situation.
Well, I can't blame them for wanting to use their tools of choice, but as a developer wanting his work to be compatible with the most popular platform, it's an unfortunate situation.
MSVC has been essentially a C++ development environment for almost 2 decades now. Asking for C99 support is a bit like asking for objective C support. MS has made it abundantly clear that it would be unprofitable for them to add C99 support on many occasions before this.
Is anyone really surprised that Microsoft continues this behavior? For the fan-boys (not that I expect there are
many): the purpose of standards, whether you like them or not, is to ease development and promote products with
actual value - not merely technology lock-in. Having maintained a C compiler for Rabbit Semiconductor and read the C99 standard, I can say it is an improvement on C90. Contrary to certain comments by Microsoft employees in the
article claiming irrelevance of C, it remains very relevant to the embedded systems community. If we, as developers,
want standards to prevail, we must eschew nonconforming implementations. You've heard of "vote with your dollars",
now "vote with your code".
[deleted]
What are some features of C99 and C11 that are not part of C++?
Designated initializers, restrict, hexadecimal floating-point literals and conversions. There are some others, but those alone are enough to prevent C++ from being interesting to me.
Most useful is variable size arrays
void func(int size) {
int array[size];
void func(int size) {
int array[size];
" If VS supported C99 natively, it would be easier for users to develop and port existing cross-platform applications."
In the words of the noted philospher and business expert - "Well duh"
In the words of the noted philospher and business expert - "Well duh"
vs sucks any way. this decision just makes it even worse.
Just install ICC (the Intel compiler). It hooks into Visual Studio, is a better compiler for both C and C++ than MSVC, works really well, produces really fast binaries, and does all its magic in the backend. Nothing changes for you, the developer.
It's both free for non-commercial development and paid for commercial dev, which makes perfect sense to me.