So it seems that with the release of Visual Studio 2005 Beta 1, Microsoft in all it's wisdom has seen fit to deprecate around one hundred standard C functions. The following is a short list some functions that have been deprecated:
Some string manipulation functions like sprintf, strcpy, and strcat.
Some string conversion functions like asctime, itoa, and fcvt.
Some input functions like scanf and cgets.
Some memory manipulation functions like memcpy and memmove.
The rand number generation function rand().
Other apparently harmless functions like printf and fopen.
All these functions have been replaced with functions that are followed by an “_s”. For example, uses of strcpy should be replaced by the function strcpy_s. Calls to rand() should be replaced by calls to rand_s(). The return types and parameter lists change also - so a simple find/replace will not work. You need to to this by hand. You can a full list of these functions here: http://msdn2.microsoft.com/library/wd3wzwts.aspx
The reason they have done this is, in a word, Security. Each of these functions and all the others that have been deprecated behave in a way that makes the production of secure code more difficult.
Many of the functions that involve copying strings in to char* variables have had a maximum allowable size argument added for example. One group of functions in particular to look out for here is the scanf() family of functions and their friends that take as parameters a destination char*, a format string, and a series of other parameters. They all have been changed in similar ways. As an example I will mention just scanf() which has been replaced by the more secure scanf_s(). The new function's signature seems to be the same as it always was:
const char *format,
The elipsis (...) indicates an unspecified list of parameters that correspond to items (type specifiers) in the format string. In the older scanf() function there was a single parameter for each item. In the new scanf_s() a second parameter is required for each one. The second item specifies the size of the buffer or variable into which the input data is copied. This is not clear from the signature and can be easily forgotten, giving usually odd results. You can read more about scanf_s() here: http://msdn2.microsoft.com/library/w40768et.aspx.
Other changes that have been made are the random number generator must be replaced with a function that creates more cryptographically secure random numbers and also many functions that used to supply information as a return value have been replaced by functions that return an error code while writing their result to an appropriate parameter pointer.
If you wish you can always turn off the security warnings by defining _CRT_SECURE_NO_DEPRACATE in your code. But this may not work forever...deprecated usually means that some day the functions will not exist anymore.
I saw one person call this modification of standard C functions “insane“. I initially though it was at the very least completely obnoxious. But it seems that there is wisdom in Microsoft's madness. So much so that the C standards committee agrees with them. Have a look at this draft Technical Report:
Though it's still only a working draft I suggest that we C programmers get used to it - a major chunk of the standard C library will soon be a fond memory. Just what will take it's place may change as far as ISO is concerned but Microsoft will soon have Visual Studio 2005 ready and after that the new functions will be written in stone - as difficult to change as, well, as the C standard runtime library.
I was surprised to find - and you might be surprised to hear - that Microsoft decided not to allow even pure .NET applications that were built on 32-bit machines with certain versions of Visual Studio to run on the 64-bit CLR.
“What are you talking about?” I hear you ask. Well, I mean that if you have a C# application that is pure, safe, 100% .NET intermediate language it may still only be allowed to run on the 32-bit CLR. Applications built by newer versions of Visual Studio .NET 2005 (code named Whidbey), however, will be allowed to run in the 64-bit CLR. Don’t worry, these same applications will work fine on 32-bit CLRs too.
“But”, I hear you insist, “.NET provides platform independence! It has no native machine code! It is pure IL that runs on the CLR. The IL has not changed in 64-bit – so why wouldn’t run on the 64-bit CLR?”
These are good questions. The answer to these questions is, unfortunately, “Just in case!” It is possible, for example, to create pure .NET code that makes use of in-process COM objects that are not pure .NET. In fact it is possible to try to load DLL’s that were not even compiled for the same platform that your .NET application is running on – if you do this your application will not find the DLL or, worse, it will die a horrible death. And the key is that it’s possible to do it without the CLR knowing that you are going to do it at application load time.
So, for example, you can create a C# application that load’s a 32-bit DLL and calls some of the functions in that DLL. If that C# application is loaded into the 64-bit CLR then any attempt to load the same 32-bit DLL will fail.
Clearly, if the OS knew FOR SURE at load time that you had no 32-bit dependencies then your application could be loaded quite safely into the 64-bit CLR. However, 1.0 and 1.1 assemblies no nothing of “bitness” – they were built by compilers that do not know anything about the 64-bit edition of Windows. So, although they can be marked as containing only IL, they may still have 32-bit dependencies in there somewhere. So, to prevent older .NET applications from breaking in unexpected ways on 64-bit Windows the CLR team decided to force them to run in the WOW on the 32-bit CLR.
Interestingly this restriction does not extend to DLL’s that are loaded by applications that manage to be executed by the 64-bit CLR. If I compile my application with Whidbey and target AnyCPU the application will load into the 64-bit CLR. If I then reference any older assemblies from my application they will be allowed to load. So be careful doing this, if the older referenced assemblies do anything that is x86 specific your application may crash.
So, let’s look at the application loading policy used by the new Windows 64-bit operating system and the .NET Framework. The loading policy is just starting to get complicated enough that a diagram would help a lot here…
The flow chart above goes like this…
- First, the file format is checked. If it is PE32+ then it is clearly a 64-bit application. PE32+ is the new 64-bit executable file format. If you target AnyCPU or x86 in Whidbey then the PE32 file format is used to ensure that it will run in 32-bit Windows.
- Next, if the file is not a .NET application then it is loaded into the WOW.
- If it is a .NET application but it is not marked as ILONLY it is loaded into the WOW.
- If it IS marked as ILONLY, but was compiled by an older compiler then, “just in case”, it is loaded into the WOW.
- Finally, if it is an ILONLY .NET assembly and was compiled by Whidbey then it checks to see if it was explicitly marked by Whidbey as requiring the 32-bit runtime. If so then it is loaded in the WOW.
- Otherwise it is loaded into the 64-bit runtime.
There is an interesting aside here. As I mentioned earlier, assemblies that were compiled by Whidbey and marked as AnyCPU use the PE32 format for executable files. Some skullduggery is required to allow this file to load into the 64-bit runtime which expects the PE32+ format. A process that has “hack” written all over it has the CLR modify the format of the file and then pass it back to the OS which eventually passes it pack to the CLR for execution.
So, the take away here is if you want your .NET applications to load in the 64-bit CLR on 64-bit machines and still work on 32-bit machines then compile them with Visual Studio 2005 and mark them as AnyCPU (which sets the ILONLY flag).
So, it’s Monday evening (21st February,2005). I want to go a friend’s house for our regular Monday night get-together. But before I go I should tell you a bit about our first Route64 event which just took place in Redmond, Wasington.
It was a great success! One comment we got was “these training sessions set the standards to what all Microsoft training events should strive for”! If that doesn’t irritate the hell out of some hardworking MS trainers out there I will eat my hat! Other comments were “Mind-blowing” and “WOW!”. As you can imagine we are more than a little pleased. Though I can’t help wondering if someone slipped something into the lunch boxes we gave them during the event…
All joking aside, it was great to see some real world applications being ported. It was also encouraging to see people making progress during the only three days of the event.
One of the original programmers of Autocad was there with his new product and, with the help of the instruction that he received during the training, managed to port his entire application to the x64 servers by the end of the second day. Some alignment problems slowed down the port to the Itaniums. Visual Studio couldn’t debug the peculiar problem that we were getting - not sure why – but we got a closer look with the help of the native 64-bit compiler WinDBG. Although the port to the Itanium was not completed by the end of the third day this attendee went home a very happy customer.
Another attendee was quite surprised to see so many warnings about the standard printf() functions. The warning said that these functions were deprecated! What’s going on he wanted to know – is Microsoft deprecating standard C now? Well, in a nutshell, the answer is “Yes“. But they are getting a lot of support for these efforts. I will write something on this shortly - watch this space.
Other noteworthy revelations from this event? How about free ice cream hidden in the small kitchen beside the “Thunder” conference room? It seems that there has been a refrigerator there for a year or two – well I never saw it before – it was so well hidden. Only accessible by those privileged few who knew where to look! Terrible elitism I call it. Snobbery in fact. Having said that, I am not giving any more information about how to find it – lest it all be gone the next time I look for my favorite sweet, icey, sugary snack...