(This is the first of two articles on changes to the C Runtime (CRT) in the Visual Studio “14” CTP. This article discusses the major architectural changes to the libraries; the second article will enumerate the new features, bug fixes, and breaking changes.)
For the past seven releases of Visual Studio (2002, 2003, 2005, 2008, 2010, 2012, and 2013), the Visual C++ libraries have been versioned and each versioned set of libraries is independent of other versioned sets of libraries. For example, a C++ program built with Visual C++ 2010 using the DLL runtime libraries will depend on msvcr100.dll and msvcp100.dll, while a C++ program built with Visual C++ 2013 will depend on msvcr120.dll and msvcp120.dll.
On the one hand, this model of introducing differently named and completely independent sets of libraries each release makes it a bit easier for us to add new features and fix bugs. We can make breaking changes, e.g. to fix nonconforming or buggy behavior, at any time without worrying about breaking existing software components that depend on already-released versions of these libraries.
However, we have frequently heard from you, our customers, that this model is burdensome and in some cases makes it difficult to adopt new versions of Visual C++ due to dependencies on modules built with an older version of Visual C++ or the need to support plugins built with a particular version of Visual C++.
This problem has grown especially acute in recent years for two reasons. First, we have accelerated the release schedule of Visual Studio in order to make new features available more frequently. Second, it has become very important to support devices smaller than desktops or laptops, like phones, and accumulating multiple copies of very similar libraries on such devices is less than ideal.
Even for us, this model of introducing new versions of the libraries can be painful at times. It makes it very expensive for us to fix bugs in already-released versions of the libraries because we are no longer actively working in the codebases for those versions, so fixes must be individually backported and tested. The result is that we usually fix only serious security vulnerabilities in old versions of the libraries. Other bugs are generally fixed only for the next major version.
We can’t fix the past: the versions of these libraries that have already been released are not going away. But we are going to try to make improvements to this experience for the future. This is a major undertaking and will take some time, but we plan to make gradual process, starting with…
The Refactoring of the CRT
The CRT sits at the bottom of the Visual C++ libraries stack: the rest of the libraries depend on it and practically all native modules depend on it as well. It contains two kinds of stuff: [1] the C Standard Library and various extensions, and [2] runtime functionality required for things like process startup and exception handling. Because the CRT sits at the bottom of the stack, it is the logical place to start the process of stabilizing the libraries.
Starting with Visual Studio “14,” we will stop releasing new versions of the CRT with each release of Visual Studio. Whereas before we would have released msvcr140.dll in this forthcoming release, then msvcr150.dll in the next release, we will instead release one new CRT in Visual Studio “14” then update that version in-place in subsequent releases, maintaining backwards compatibility for existing programs.
We are also working to unify the CRTs used for different platforms. In Visual Studio 2013, we built separate “flavors” of the CRT for different platforms. For example, we had separate CRTs for desktop apps, Windows Store apps, and Windows Phone apps. We did so because of differences in which Windows API functions are available on different platforms.
In Windows Store and Windows Phone apps, only a subset of the Windows API is available for use, so we need to implement some functions differently and cannot implement other functions at all (for example, there’s no console in Windows Store and Windows Phone apps, so we don’t provide the console I/O functionality in the CRT). The CRT for desktop apps must run on all supported operating systems (in Visual Studio 2013 this included Windows XP) and must provide the full set of functionality, including legacy functionality.
In order to unify these different CRTs, we have split the CRT into three pieces:
-
VCRuntime (vcruntime140.dll): This DLL contains all of the runtime functionality required for things like process startup and exception handling, and functionality that is coupled to the compiler for one reason or another. We may need to make breaking changes to this library in the future.
-
AppCRT (appcrt140.dll): This DLL contains all of the functionality that is usable on all platforms. This includes the heap, the math library, the stdio and locale libraries, most of the string manipulation functions, the time library, and a handful of other functions. We will maintain backwards compatibility for this part of the CRT.
-
DesktopCRT (desktopcrt140.dll): This DLL contains all of the functionality that is usable only by desktop apps. Notably, this includes the functions for working with multibyte strings, the exec and spawn process management functions, and the direct-to-console I/O functions. We will maintain backwards compatibility for this part of the CRT.
While I’ve named the release DLLs in the list, there are also equivalent debug DLLs and release and debug static CRT libraries for each of these. The usual lib files (msvcrt.lib, libcmt.lib, etc.) are built such that the newly refactored CRT is a drop-in replacement for the old CRT at build-time, so long as /nodefaultlib is not used.
While we have retained the version number in the DLL for this CTP, we plan to remove it from the AppCRT and DesktopCRT before the final release of Visual Studio “14,” since we will be updating those DLLs in-place. Finally, we are still working on the final packaging of functionality, so we may move things among the DLLs before the final release.
Windows Store and Windows Phone apps will be able to use the functionality from the VCRuntime and the AppCRT only; desktop apps will be able to use all of that functionality plus the functionality from the DesktopCRT. In this first Visual Studio “14” CTP, all apps depend on all three parts of the refactored CRT; this is merely a temporary state of affairs that will be fixed eventually.
The Problem of Maintainability
One of the biggest problems that we had to solve in order to consider stabilizing the libraries in this way was the problem of maintainability. The CRT is a very old codebase, with many source files dating back to the 1980s. In many parts of the code, optimization techniques that were valid and useful decades ago not only obfuscated the code and made it difficult to maintain, but also hampered the modern compiler’s ability to optimize the code. In other areas, years of bolted-on features and bug fixes had turned once-beautiful C code into a hideous maintenance nightmare. If we were going to consider stabilizing the libraries so that we could update them in-place, we’d need to improve the maintainability first, otherwise we’d incur great cost to fix bugs and make improvements later.
The “best” example of this maintainability problem could be found in the old implementation of the printf family of functions. The CRT provides 142 different variations of printf, but most of the behavior is the same for all of the functions, so there are a set of common implementation functions that do the bulk of the work. These common implementation functions were all defined in output.c in the CRT sources(1). This 2,696 line file had 223 conditionally compiled regions of code (#ifdef, #else, etc.), over half of which were in a single 1,400 line function. This file was compiled 12 different ways to generate all of the common implementation functions. Even with the large number of tests that we have for these functions, the code was exceedingly brittle and difficult to modify.
This isn’t merely a theoretical problem. In Visual Studio 2013, we added many of the C99 functions that were previously missing (see Pat’s blog post from last year). However, there were a number of things that we were unable to implement. Two of the most conspicuous missing features were [1] the snprintf function and [2] the format string enhancements like the z and t length modifiers for the size_t and ptrdiff_t types. It was late in the product cycle when we started looking at implementing these, and decided we simply could not implement them with confidence that we weren’t breaking anything.
So, as part of this great refactoring of the CRT, we have done an enormous amount of work to simplify and improve the quality of the code, so that it is easier to add features and fix bugs in the future. We have converted most of the CRT sources to compile as C++, enabling us to replace many ugly C idioms with simpler and more advanced C++ constructs. The publicly callable functions are still declared as C functions, of course (extern "C" in C++), so they can still be called from C. But internally we now take full advantage of the C++ language and its many useful features.
We have eliminated most of the manual resource management in the code through the introduction of several special-purpose smart pointer and handle types. Enormous functions have been split into smaller, maintainable pieces. We have eliminated 75%(2) of the conditional compilation preprocessor directives (#ifdef, #else, etc.) by converting internal implementation details to use C++ features like templates and overloading. We have converted most of the CRT source files to use a common coding style.
As part of this work, we’ve completely rewritten the core implementations of the printf and scanf functions (now with no #ifdefs!). This has enabled us to implement the remaining C99 features for the stdio library, to improve correctness checks in the library, and to fix many conformance bugs and quirks. Just as importantly, this work has enabled us to discover and fix substantial performance issues in the library.
Before this refactoring, the sprintf functions, which write formatted data to a character buffer, were implemented by wrapping the result buffer in a temporary FILE object and then deferring to the equivalent fprintf function. This worked and produced the correct result, but it was exceedingly inefficient. When writing characters to a FILE we need to be careful to handle many cases like buffer exhaustion, end-of-line conversions, and character conversions. When writing characters to a string, we should simply be able to write through and increment the result pointer. After the refactoring, we were easily able to identify this performance problem and, more importantly, fix it. The sprintf functions are now up to 8 times faster than they were in previous releases.
This is merely one example of where we’ve done major work and how that work has helped us to improve the quality of the library. In the next article we will enumerate all of the major features, bug fixes, and breaking changes to the CRT in the Visual Studio “14” CTP, similar to what Stephan wrote last week for the STL.
What Next?
We are nearing completion of the CRT refactoring. Undoubtedly there are bugs, and we encourage you to try out the Visual Studio “14” CTP and report any bugs that you find on Microsoft Connect. If you report bugs now, there’s a really good chance that we can fix them before the final release of Visual Studio “14.” We’ve already gotten a few bug reports; thank you to those of you who reported them!
We are investigating opportunities for similar stabilization efforts with other libraries. Given that the separately-compiled STL components (msvcp140.dll) are also very commonly used, we are considering our options for a similar stabilization of that functionality.
Note that near-term we are only considering stabilization of the separately-compiled code. We do not plan to make stability guarantees about any C++ Standard Library types or any inline code in the C++ headers. So, for example, if you pass a std::vector to a function, both the caller and callee will still need to be compiled with the same STL headers and options. There are very long-term efforts to try to come up with a solution to this more general problem; for example, see Herb Sutter’s recent C++ Standardization Committee proposal N4028: Defining a Portable C++ ABI.
James McNellis (james.mcnellis@microsoft.com)
Senior Software Development Engineer, Visual C++ Libraries
(1) We ship most of the sources for the CRT with Visual Studio; you can find them in the Visual Studio installation directory under VCcrtsrc.
(2) In Visual Studio 2013 there are 6,830 #if, #ifdef, #ifndef, #elif, and #else directives in the sources that we ship with the product; in the Visual Studio “14” CTP there are 1,656. These numbers do not include directives in headers and they do include the STL source files which are largely untouched by this refactoring effort, so this isn’t a perfect measurement, but it’s indicative of the amount of cleanup that’s been done.

Great job! Very cool.
One thing you didn't mention that I'm curious about — what is the behavior when I compile something using a new CRT feature in VS2015, but the user only has VS2014's CRT installed and tries to run the app?
Not sure about the new names, shouldn't they begin 'ms'. Makes them more immediately recognisable as Microsoft product.
This is very good news indeed. My team was struggling with the zoo of C++ runtime libraries required since time immemorial.
But what about compatibility of static libraries between compiler releases? As currently stands, it seems Microsoft guarantees forward/backward compatibility within VS release (2010, 2012, 2013, etc.), but there are no compatibility guarantees between compiler versions. There are not even any workarounds (like limiting features used in APIs) or guidelines to make sure that, for example, VS2013 can successfully build against VS2010-produced .lib.
In a large org feeding into one binary, this makes VS adoption all-or-nothing deal, slowing it considerably.
Removing the version number from the dll name will make it harder to maintain backwards compatibility in the future (from your perspective). From my perspective as a developer I'm not interested in a dll that carries all the baggage from the past. Please reconsider this change.
On another note I have always wondered why you aren't able to deploy the crt through Windows Update as important updates? It makes no sense that every single application compiled with VS must include the CRT redistributable.
What about the deployment story? Sad as it is, using vcredist seems to be a lingering, but frequent means of deploying the vc runtime (plus MFC et al.), but that has its own headaches (oh- you need the update 4 version, but you only have the update 2 version installed….ugh.)
Great work!
Here's to hoping we will one day see C99 support in full. The compiler seems to have some important pieces already in place in C++ mode. Our project (neovim) uses some C99 features like declare-anywhere, compound literals, VLAs (but we could live without that, only have one in the codebase), automatic cast from void (looks so much cleaner), designated initializers (cleanliness as well) and that's about it. We'd love to see it work with MSVC as well. As it stands, we'll have to get mingw/gcc or clang to compile it, to provide a working version to our windows users. I'll be watching out for news!
Any changes related to the "known dll" msvcrt.dll system component that may affect mingw/mingw-w64 toolchain users?
Nicolas> declare-anywhere, compound literals […] designated initializers
Implemented in VS 2013. See blogs.msdn.com/…/c-11-14-stl-features-fixes-and-breaking-changes-in-vs-2013.aspx from last year.
> automatic cast from void (looks so much cleaner)
This isn't a C99 feature. C89 allowed void * to implicitly convert to X *. (C++98 sensibly removed this massive hole in the type system.)
"Here's to hoping we will one day see C99 support in full. "
Please, please, please.
awesome, finally, thank you thank you thank you! The missing backwards compatibility always had me release many versions of my library, instead of a single one. I'm so happy when this is over.
Thanks for a great write-up!
I'm wondering functions like _snprintf. _snprintf (not _sprintf) has been there for a long time. So far, I used a wrapper function for simulating snprintf behavior. It looks like _snprintf is a separate implementation. Can you give us more information about _-prefixed functions? Thanks!
"In order to unify these different CRTs, we have split the CRT into three pieces:"
please read that.
I wonder how this compares to MSVCRT from the VC4.2/5/6 days.
Was this work inspired by the refactoring made in GCC and LLVM?
It might sound nuts for a Microsoft product but didn't you guys think of using LLVM instead of playing catch up? The license is permissive, you don't have to contribute code if you don't want to and you can use it at your own desire… I think everyone would win from that.
Btw, I understand you've put a lot of effort in but you should seriously consider this option. The cloud and the server adapted to the reality of the current situation…
I agree with Lilian, how awesome would it be to have Visual Studio with clang instead. It seems the clang guys are working on it, but Microsoft is trying to catch up with their own compiler.
Cory: what is the behavior when I compile something using a new CRT feature in VS2015, but the user only has VS2014's CRT installed and tries to run the app?
Apps that use the CRT will still be responsible for ensuring that the right version of the CRT is installed. For example, if you build an app with VS15, you’ll need to ensure that you install the redist for the VS15 CRT. If the VS14 CRT is already installed, the VS15 CRT will replace it, and anything that was using the VS14 CRT will continue to work with the new VS15 CRT. [Disclaimer: I’m not saying there will be anything called VS15; I’m merely using this as a placeholder for “the thing that comes after Visual Studio ‘14’.”]
BG: Not sure about the new names, shouldn't they begin 'ms'. Makes them more immediately recognizable as Microsoft product.
Most Microsoft-provided DLLs are not prefixed with “ms.” As an example, relatively few operating system DLLs in the system directory (system32 or syswow64) are prefixed with “ms.”
Sergey: What about compatibility of static libraries between compiler releases?
All objects built into a single module (DLL or EXE) should be built using the same compiler and library headers, and with the same compilation options. Trying to mix-and-match objects compiled with different compilers or with different library headers (or with different options that affect things like object layout or inlining) will very likely result in one-definition rule (ODR) violations, which are often quite difficult to debug.
If you need to build parts of your system with different compilers or library headers (or with different options), you should split your system into multiple modules (DLLs) so that the parts built with each toolchain and library set are isolated.
CMC: “using vcredist seems to be a lingering, but frequent means of deploying the vc runtime (plus MFC et al.), but that has its own headaches”
Apps will still be required to ensure that the correct version of the Visual C++ Libraries are installed. There will still be a redist, just like there is today; the only difference is that some DLLs will be updated in-place by newer redists.
Jon: Any changes related to the "known dll" msvcrt.dll system component that may affect mingw/mingw-w64 toolchain users?
There are no changes to any operating system components (like msvcrt.dll) in what we have delivered in the Visual Studio “14” CTP.
Kay: I'm wondering functions like _snprintf. _snprintf (not _sprintf) has been there for a long time…Can you give us more information about _-prefixed functions?
If you call _snprintf with an insufficiently large buffer, the buffer is not null-terminated and a negative value is returned. If you call snprintf with an insufficiently large buffer, the buffer is null terminated, and the value returned is the number of characters that would have been written to the buffer had it been sufficiently large.
Lilian: Didn't you guys think of using LLVM instead of playing catch up?
Even if we switched to use a different toolchain, we’d still need a good C Standard Library implementation on the Windows platforms. The MinGW toolchain on Windows uses the old Visual C++ 6 CRT (msvcrt.dll). When I last looked at the Clang/LLVM package for Windows, they compiled and linked with a recent version of the Visual C++ CRT.
1- Can you please point out which "C99 Standard Library features" and "C99 Core Language features" are missing from VS2013 Update 2 and VS2014 CTP 1?
2- Will we get <uchar.h> in VS2013 and / or VS214?
3- Does <tgmath> stand a chance to make its way to MSVC ever?
4- Since some C11 features are pre-requisite for many C++14 features, can we expect full/partial C11 support in VS at some point?
Thanks for this great elaborated article James and please keep coming back on VC blog!
Will MFC MBCS lib for vs14 would be continue proveded?
What difference does it make how the toolchain works when the whole windows platform is unstable due to careless defects such as cryptolocker or sasser ? No one who cares about reliability would ever use a microsoft product.
This is huge! Big relief to plugin developers, once mainstream products move on the VS2014 (Autodesk for example)
"142 different variations of printf"!
Out of curiosity I took a look at the output.c file you mentioned and what it looks like in the VS2013RTM.
It's dungeons and dragons there! You guys are brave, fearless people for even considering touching it 🙂
Great work!
A question somebody asked earlier: with this new in-place approach would it be possible to make the CRT part of the system release and updates? What is the driver for it being a separate redist, that developer needs to worry about?
This all sounds great but I'll only believe it when I see it.
a) Congrats on the refactoring and speed improvements
b) So it's DLL hell all over again? One CRT.DLL to rule them all, and woe if you're unknowingly depending on an old version's quirks? (ah well, you can always deploy the exact version in the app directory.)
c) quote:"… and anything that was using the VS14 CRT will continue to work with the new VS15 CRT" – yeah, *right*. I admire your confidence.
I'm not so sure this (one crt DLL to rule them all) is a such good thing, then again, I'm not sure the per-VS-Versions were a good thing either.
Have thoughts gone into versioning the CRT (et al.) independently from VS?
@Terry:
What, and go to a platform that gives us heartbleed?
Remember that a lot of the Operating System defects are found due to Windows being a more popular desktop system, so it is more profitable. That doesn't make it any less secure, it just means that there is more worth in finding these defects.
If the situation was reversed, how different do you think it would be? People would be scouring the *nix code to find these defects due to them being worth more and probably finding a lot more than you realise.
Anyway, on a more interesting topic.
On the topic of the refactored CRT and MSVCRT. Are the large portion of the runtime functions going to be in the backwards compatible parts of the CRT and things like the exception handling, type lookup and other things in the versioned parts? I'm curious about this because MSVCRT is normally used for getting access to the runtime functions and the other services are statically linked.
This could give one more reason to stop using MSVCRT and a viable alternative.
Does it properly support UTF-8 now? That has always been a long term complaint and one that needs to be redressed.
Guys here is what you should do:
– Download the free Windows 8.1 VM: modern.ie/…/virtualization-tools
– Download the free VS2014 CPT.
– Run VM and install VS2014 CPT in it.
On a good internet connection and strong powerful machine, all this can be setup in less than 30 minutes (I dedicated 4 GB of RAM to the readymade VM from the aforementioned Internet Explorer website).
Get all the answers by "TRYING" it out and _then_ send the feedback here or Connect; what's working and what's not, performance comparisons (befores and afters), geeky interesting stuff! Its C-Lang we are talking about, so act like it here PLEASE!
And how about the ups-this-was-a-breaking-change-even-intended-as-bug-fix updates?
After having some separate and great co-existing .NET framework version now we have in already 3 inplace updates for .NET4 and all of them came with such "bug fixes".
Like "Martin Ba" I recommend to check releasing CRT independed of VS version.
Great job. Implementation of legacy C functions using C++ templates will go a long way in making these functions superefficient and portable.
I find this astounding, does anyone else?
QUOTE
Before this refactoring, the sprintf functions, which write formatted data to a character buffer, were implemented by wrapping the result buffer in a temporary FILE object and then deferring to the equivalent fprintf function. This worked and produced the correct result, but it was exceedingly inefficient.
END QUOTE
@Ed Patterson,
Yeah that was the ouch moment for me. James didn't mentioned how they fixed it though! I mean do they still depend on FILE object? Although, I am happy to see that significant performance, I would love to know more (as you can tell I am so into performance: blogs.msdn.com/…/bugs-fixed-in-the-spring-update.aspx)
@Super Mario:
He basically describes it in the post "When writing characters to a string, we should simply be able to write through and increment the result pointer". So, they write directly to a string, instead of a file.
As James (kinda) said, look in C:Program Files (x86)Microsoft Visual Studio 14.0VCcrtsrcappcrtoutput.cpp. there are two main functions, common_vfprintf and common_vsprintf. They defer to an internal output_processor class template. vfprintf provides a template parameter that delegates its writes to a FILE, vsprintf provides a template parameter that delegates its writes to a string.
So, basically: classes, templates, variadic templates, and lambdas (well, the lambdas aren't a key component of that, the change). Which are all weird to see in the implementation of a C API. But, they all make sense given the desired cleanup to tear apart the #if's, and the normal way of doing that in C++ would be classes and templates (or classes and virtual functions).
Also, the "getting rid of number from dll name" had odd timing given this recent-ish post blogs.msdn.com/…/10516280.aspx and its compatibility issue notes.
Tony Rance: I don’t have a list of which C99 and C11 language features are and are not supported. For library features, the Visual Studio “14” CTP includes almost everything from the C99 Standard Library that does not require compiler support. For example, <tgmath.h> and various pragmas are not supported for this reason. There are a few omissions that we know of (_Exit is missing; our wcstok has the incorrect signature), and there undoubtedly a few bugs, but otherwise everything should be implemented. If you find any C99 library conformance issues that could be resolved without additional compiler support, please report them on Microsoft Connect.
We do plan to implement <uchar.h>, we just haven’t done so yet. It’s high on our list of priorities, as is support for Unicode string literals.
Krzysztof Kawa: Even if the CRT was integrated into the operating system and even if it was pushed out to “older” OSes via Windows Update, app installers would still need to include a redist of some kind (perhaps a Windows Update package) to handle the case where the CRT hasn’t yet been installed on the machine (not everyone installs Windows Updates immediately, especially non-security updates). We have considered many options for improving the distribution experience, and there’s no “perfect” solution.
Crescens2k: Yes. The VCRuntime (the “versioned parts”) contains the exception handling and RTTI logic, support for various compiler features (/GS checks, the purecall handler, and other miscellaneous things), and some of the string handling functions (like memcpy, strlen, etc.). Everything else is in the AppCRT and DesktopCRT (the “backwards compatible parts”).
Kantos: No, UTF-8 locales are not supported.
Ed Patterson, Super Mario, Michael: Right. We generalized the formatting operation over an abstract “OutputAdapter” that handles the writing of characters to a FILE, to the console, to a string, or wherever. We can use most C++ features that do not require runtime support.
@James McNellis
I see apps crashing without explanation because of some missing KBxyz pretty frequently. Skype and facebook video chat do that to name some popular ones 😉 I'm not saying this is a good thing but it just wouldn't be anything new. Oh well, I guess dlls were both greatest and worst inventions of their time and we'll need to live with them for what they are.
Btw. I would love to hear what other ideas you considered. I bet that would be a great read 😉 I can imagine a few of my own and they too are flawed in one way or another or radically changing things (rendering them impossible to introduce now).
Very nice. I would hope that those silly Luddites who avoid C++ and stick with C because they think that it's faster will read this.
Is it correct that, at this time, calls to sprintf are "deferred" to fprintf except when using Visual Studio 14? If so, does the same apply to sscanf and fscanf?
"If so, does the same apply to sscanf and fscanf?"
Yes. But the temporary FILE object thing is a bit misleading. Someone may think that it involves an actual temporary file but that's not the case, there's no actual file involved. It's just that the input/output char array is used as the buffer of a FILE object created by the sscanf/sprints functions, without fopen being involved.
"Someone may think that it involves an actual temporary file", I did and it's nice to know it doesn't.
BG> Not sure about the new names, shouldn't they begin 'ms'. Makes them more immediately recognisable as Microsoft product.
I agree. It would be best if the files would be names according to some "namespace" such as mscrt_app.dll, mscrt_desktop.dll and mscrt.dll.
To be succinct in up-to 140 chars: ISO C++11/14 will be vcruntime140.dll…, C++17/19 ought to be vcruntime17.dll with minor version updating taken care of by Windows Update.
Is this correct?
Wow, what a pendulum swing. Still trying to make sense of it
Windows 95 era – msvcrt.dll – DLL Hell – causes chaos when you break existing subtle memory behaviour (crashing many apps) – KnownDLL era as well.
Windows 2000 era – msvcrt.dll under system file protection – better
Visual Studio 2002/2003 era – msvcr70/71 installed to system32 – isolated to the version you build with but DLL Hell in system32 (worse if bad installers come along and mess with yours since they're not under WFP)
Visual Studio 2005/2008 era – msvcr80/90 installed to WinSxS, but for all intents and purposes same DLL Hell issues as before since there are redirects set up so that manifests always get the latest, some hacks though
Visual Studio 2010/2012/2013 era – msvcr100/110/120 we're back to system32 same model as 2002 and 2003 but maybe they're protected a bit better by trustedinstaller. Still DLL Hell.
Visual Studio 2015+ – new DLLs can came along in system32 any time in the future and blow your app up or introduce security bugs (no longer isolated by compiler version) – super DLL Hell era. Onus is completely on Microsoft for "getting it right".
My question is, how do you intend to handle the DLL Hell issue?
Glad to see Microsoft finally supports C99!!
Please take this opportunity fix your unicode situation in your C runtime. We ought to be able to pass UTF-8 strings to the standard I/O functions. When I write cross-platform code, I always have to stand on my head because on Windows, I have to convert everything to utf16.
Even if you give a set of API routines with differing names, ie…open_utf8()… that is easy to deal with. Having to deal with two different text encodings with existing compilers is a major pain.
Perhaps the better solution is to provide a proper codepage so that existing ANSI functions can be configured to handle UTF8 input and output.
The other problem you have is the interfacing of char16_t to wchar_t. If was very awkward trying to work with c++11 code using Win32 APIs and your standard C library functions. It would be nice if the utf16 versions of functions would accept the output of std::u16string::c_str() without casts and std::u16string functions would accept wchar_t/wchar_t* without casts on Windows. However, the system is adjusted to make the code cleanly work without macro hacking or casts all over the place is fine with me.
-James
When I watch Microsoft technical presentations on native tools, I'm always left with the impression that the native tools teams are woefully understaffed. I cannot understand how a technology company with the size and resources of Microsoft has compilers and libraries that appear to be so far behind the times.
When I work on cross-platform code, I'm always shocked at little things that don't work or what appears to be hacked or contrived behaviors in your C++ infrastructure. It looks like you have too few people trying to do too much and you are shipping half-baked work as a result.
if that is true, Microsoft needs to spend less money on C# and .NET…and all the tinker-toy tools for IT Dilbert's…and beef up the native compiler and library teams to better support big boy developers.
I've watched the presentations on the new Swift language. That is a big-boy language and it solves pretty much all of the problems inherent to Cocoa development and native development in general without garbage collectors or virtual machines to get in your way. Apple is investing heavily in developing big-boy tools that solve the problems. As a result, their systems and 3rd party apps are going to be more robust, performant, and maintainable over time.
Microsoft had better be paying attention to what the competition is doing and investing just as heavily in their native tools. WinRT and its C++ extensions looks like a promising start, but until it can support desktop development, one has no choice but to stick with awkward, hard-to-maintain win32 code. Win32 needs to go the way of the classic Mac toolbox (aka "Carbon")!
BTW: since most of your customers are migrating to Win 7 rather than Win 8, WinRT needs to work on Win 7 until you figure out a way to get people to like Windows 8.
-James
When I watch Microsoft technical presentations on native tools, I'm always left with the impression that the native tools teams are woefully understaffed. I cannot understand how a technology company with the size and resources of Microsoft has compilers and libraries that appear to be so far behind the times.
When I work on cross-platform code, I'm always shocked at little things that don't work or what appears to be hacked or contrived behaviors in your C++ infrastructure. It looks like you have too few people trying to do too much and you are shipping half-baked work as a result.
if that is true, Microsoft needs to spend less money on C# and .NET…and all the tinker-toy tools for IT Dilbert's…and beef up the native compiler and library teams to better support big boy developers.
I've watched the presentations on the new Swift language. That is a big-boy language and it solves pretty much all of the problems inherent to Cocoa development and native development in general without garbage collectors or virtual machines to get in your way. Apple is investing heavily in developing big-boy tools that solve the problems. As a result, their systems and 3rd party apps are going to be more robust, performant, and maintainable over time.
Microsoft had better be paying attention to what the competition is doing and investing just as heavily in their native tools. WinRT and its C++ extensions looks like a promising start, but until it can support desktop development, one has no choice but to stick with awkward, hard-to-maintain win32 code. Win32 needs to go the way of the classic Mac toolbox (aka "Carbon")!
BTW: since most of your customers are migrating to Win 7 rather than Win 8, WinRT needs to work on Win 7 until you figure out a way to get people to like Windows 8.
-James
@James,
Seriously! What is the alternate of System.Linq in your big-boy beloved language? Have you heard of .NET Native yet? Yes Microsoft has already invested their resources on .NET native to sidestep GC and VM.
Nevertheless, C++ remains the most portable language of the World in #2014! No need to create another proprietary spaghetti language like that..
Try to be:
1- "appreciative" of what has been done and what's scheduled to come your way.
2. "productive" by providing the useful feedback.
Thanks for the answer Stephan!
One thing confuses me though:
> This isn't a C99 feature. C89 allowed void * to implicitly convert to X *. (C++98 sensibly removed this massive hole in the type system.)
Yes, that's true, but is there any way at all we can force MSVC to accept these things in the same mode (compilation run)? We use both cast-less void conversions AND designated initializers AND compound literals…
Put shortly: how are we supposed to invoke cl.exe? Or run from within MSVC? We are interested in bringing our open-source project to Windows, but we haven't been having a too easy time and we don't want to backpedal on leaving C89 behind.
Nicolas:
Um. invoke cl.exe as normal?
>type Thing.c
#include <stdlib.h>
typedef struct {
int y, x;
} Point;
struct foo { int a; char b[2]; } structure;
int main(void) {
// implicit cast from void*
Point* p = malloc(sizeof(Point));
// designated initializers
Point x = { .x = -10, .y = 5401};
p->x = 10;
p->y = 104;
// compound literals
structure = ((struct foo) {p->x + x.y, 'a', 0});
free(p);
return 0;
}
>cl Thing.c
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.30501 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
Thing.c
Microsoft (R) Incremental Linker Version 12.00.30501.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:Thing.exe
Thing.obj
If you wanted to be explicit, there's the /TC and /Tc command line options to force C compilation regardless of the file extension. In Visual Studio, it's settable with the "Compile As" option. Which is <CompileAs> in the vcxproj file. And as Stephan said, that's all just in VS2013.
Or did you want those three things AND C++ stuff? It looks like neovim only has .c files, since it's using CMake, does CMake have an option to force that setting? Or does it force the CompileAs option to something other than Default?
Hey Michael,
Thanks a lot for the reply. In your example I see many of the C99 features I would like to see (except for declare-anywhere), so perhaps we've been missing just some small things.
You are correct in your assertion that neovim has only .c files. We try to adhere strictly to the C99 standard. So if you say all of these things are possible, then I'm not sure why we're (currently) still failing. But we'll get there.
For reference, this is the "getting neovim on msvc" issue: github.com/…/696.
Sorry for double-posting Michael, but we got a bit further after confirming that MSVC 2013 nominally _does_ support declare anywhere.
The reason we were confused is because of some (seemingly) obscure frontend/parser bug. It's detailed in this neovim issue: github.com/…/696
It seems like MSVC 2013 doesn't accept declaring after a braceless control statement:
if (1)
printf("fails!");
Point x = { .x = -10, .y = 5401};
doesn't work
if (1) {
printf("fails!");
}
Point x = { .x = -10, .y = 5401};
works.
Because braceless statements do appear in our code, I thought declare-anywhere was not supported.
@Nicolas: tried that with Visual Studio 2013 Update 2 installation, but can't reproduce the issue 🙁
I created a file test.c with following content:
#include<stdio.h>
int main()
{
printf("Hello Worldn");
if (1)
printf("Hellon");
if (2)
{
printf("World");
}
return 0;
}
Then in Developer Command Prompt:
C:temp>cl test.c && test
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.30501 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
test.c
Microsoft (R) Incremental Linker Version 12.00.30501.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:test.exe
test.obj
Hello World
Hello
World
C:temp>
As you can see, it seems to work just fine..
Also, you can submit the issues you discovered at connect.microsoft.com/…/CreateFeedbackForm.aspx
Sorry, this code in test.c does compile with "cl test.c" with no warning (I think @equalsraf must have missed something in his example on github):
#include <stdlib.h>
#include <stdio.h>
typedef struct {
int y, x;
} Point;
struct foo { int a; char b[2]; } structure;
int main(void) {
// implicit cast from void*
Point* p = malloc(sizeof(Point));
// designated initializers
p->x = 10;
if (1)
printf("fails!");
Point x = { .x = -10, .y = 5401 };
system("pause");
return 0;
}
Will there be a non-Unicode (Multi-Byte) version of MFC available for Visual Studio "14"? One isn't included in this CTP, and our 10+-year-old project, which has been continuously maintained and developed, relies upon it.
I don't think that it was the refactoring of *sprintf() to avoid FILE that improved its performance 8x – I think it was the fact that Microsoft removed the DecodePointer() calls from *sprintf(). DecodePointer() is an NT kernel call (NtQueryInformationProcess), which will always ruin your day when going for performance.