CRT Refactored in Visual Studio “14”

Visual Studio “14” CTP ships with a refactored C Runtime. The first thing you’ll notice is that msvcrXX.dll has been replaced by three new DLLs: appcrtXX.dll, desktopcrtXX.dll and vcruntimeXX.ddl (where XX stands for the version number so in this version it’s appcrt140.dll, desktopcrt140.dll and vcruntime140.dll).

crtdlls
You can see in this image that both desktopcrt140.dll and vcruntime140.dll depend on appcrt140.dll.

These three new DLLs export run-time routines in different categories, with some of them overlapping, as shown by the bellow table (assembled by directly analyzing the exports of the three modules).


Function

Appcrt140.dll

Desktopcrt140.dll

Vcruntime140.dll
Buffer Manipulation
Byte Classification
Character Classification
Console and Port I/O
Data Alignment
Data Conversion
Debug Routines
Directory Control
Error Handling
Exception Handling
File Handling
Floating-Point Support
Low-Level I/O
Process and Environment Control
Robustness
Searching and Sorting
Stream I/O
String Manipulation
System Calls
Time Management

Breaking CRT routines in several DLLs is not the only change. The CRT has been rewritten for safety and const correctness. Many of the routines have been re-written in C++. Here is a random example: the _open function, that was available in open.c was implemented like this in Visual Studio 2013:

int __cdecl _topen (
        const _TSCHAR *path,
        int oflag,
        ...
        )
{
        va_list ap;
        int pmode = 0;
        int fh = -1;
        errno_t retval = 0;
        int unlock_flag = 0;

        _VALIDATE_RETURN( (path != NULL), EINVAL, -1);

        va_start(ap, oflag);
        pmode = va_arg(ap, int);
        va_end(ap);

        __try {
/* Last parameter passed as 0 because we don't want to
validate pmode from open */
            retval = _tsopen_nolock( &unlock_flag,
                                 &fh,
                                 path,
                                 oflag,
                                 _SH_DENYNO,
                                 pmode,
                                 0 );
        }
        __finally {
            if ( unlock_flag )
            {
                if (retval)
                {
                    _osfile(fh) &= ~FOPEN;
                }
                _unlock_fh(fh);
            }
        }

        if (retval)
        {
            errno = retval;
            return -1;
        }

        return fh;
}

In Visual Studio “14” CTP it is available in function appcrt\open.cpp and looks like this:

template <typename Character>
static int __cdecl common_open(
    Character const* const path,
    int              const oflag,
    int              const pmode
    ) throw()
{
    typedef __crt_char_traits<Character> traits;

    _VALIDATE_RETURN(path != nullptr, EINVAL, -1);

    int fh = -1;
    int unlock_flag = 0;
    errno_t error_code = 0;
    __try
    {
        error_code = traits::tsopen_nolock(&unlock_flag, &fh, path, oflag, _SH_DENYNO, pmode, 0);
    }
    __finally
    {
        if (unlock_flag)
        {
            if (error_code)
            {
                _osfile(fh) &= ~FOPEN;
            }

            __acrt_lowio_unlock_fh(fh);
        }
    }

    if (error_code != 0)
    {
        errno = error_code;
        return -1;
    }

    return fh;
}

UPDATE

To read more about the refactoring see the VC++ team’s blog posts:

1 Reply to “CRT Refactored in Visual Studio “14””

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.