C99 library support in Visual Studio 2013

C99 library support in Visual Studio 2013

Rate This
  • Comments 26

Hello, I’m Pat Brenner, a developer on the Visual C++ Libraries team. In this blog post I want to share some information about the C99 support added to the C run-time library in Visual Studio 2013.

To summarize, we added declarations and implementations for missing functions in the following headers: math.h, ctype.h, wctype.h, stdio.h, stdlib.h, and wchar.h. We also added the new headers complex.h, stdbool.h, fenv.h, and inttypes.h, and added the implementations for all the functions declared in them. In addition, we added the new C++ wrapper headers (ccomplex, cfenv, cinttypes, ctgmath) and updated a number of others (ccomplex, cctype, clocale, cmath, cstdint, cstdio, cstring, cwchar, and cwctype).

Most of this work (all the C headers except stdbool.h and fenv.h) was done in time for the Visual Studio 2013 Preview release and is available with it, but the remainder (stdbool.h, fenv.h and the C++ wrapper headers) has been done for Visual Studio 2013 RTM and will be available with that release.

In more detail, these are the declarations and implementations we added, grouped by the headers that declare them:

  • math.h: 
    • float_t, double_t, fpclassify, isfinite isinf, isnan, isnormal, signbit
    • HUGE_VALF, HUGE_VALL, INFINITY, NAN, MATH_ERRNO, MATH_ERREXCEPT
    • FP_INFINITE, FP_NAN, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, FP_ILOGB0, FP_ILOGBNAN
    • acosh, acoshf, acoshl, asinh, asinhf, asinhl, atanh, atanhf, atanhl
    • exp2, exp2f, exp2l, expm1, expm1f, expm1l
    • ilogb, ilogbf, ilogbl, logb, logbf, logbl, log1p, log1pf, log1pl, log2, log2f, log2l
    • scalbn, scalbnf, scalbnl, scalbln, scalblnf, scalblnl
    • cbrt, cbrtf, cbrtl, erf, erff, erfl, erfc, erfcf, erfcl
    • lgamma, lgammaf, lgammal, tgamma, tgammaf, tgammal
    • nearbyint, nearbyintf, nearbyintl, nan, nanf, nanl
    • rint, rintf, rintl, lrint, lrintf, lrintl, llrint, llrintf, llrintl
    • round, roundf, roundl, lround, lroundf, lroundl, llround, llroundf, llroundl
    • trunc, truncf, truncl, remainder, remainderf, remainder, remquo, remquof, remquol
    • nextafter, nextafterf, nextafterl, nexttoward, nexttowardf, nexttowardl
    • fdim, fdimf, fdiml, fmax, fmaxf, fmaxl, fmin, fminf, fminl, fma, fmaf, fmal
  • complex.h: 
    • cacos, cacosf, cacosl, casin, casinf, casinl, catan, catanf, catanl
    • ccos, ccosf, ccosl, csin, csinf, csinl, ctan, ctanf, ctanl
    • cacosh, cacoshf, cacoshl, casinh, casinhf, casinhl, catanh, catanhf, catanhl
    • ccosh, ccoshf, ccoshl, csinh, csinhf, csinhl, ctanh, ctanhf, ctanhl
    • cexp, cexpf, cexpl, clog, clogf, clogl, cabs, cabsf, cabsl
    • cpow, cpowf, cpowl, csqrt, csqrtf, csqrtl, carg, cargf, cargl
    • cimag, cimagf, cimagl, conj, conjf, conjl, cproj, cprojf, cprojl, creal, crealf, creall
  • fenv.h: 
    • fegetenv, fesetenv, feupdateenv, fegetexceptflag, fesetexceptflag
    • feclearexcept, feholdexcept, fetestexcept, feraiseexcept
  • inttypes.h:
    • PRIi8, PRIi16, PRIi32, PRIi64, PRIiMAX, PRIiPTR, PRIiLEAST8, PRIiLEAST16, PRIiLEAST32, PRIiLEAST64, PRIiFAST8, PRIiFAST16, PRIiFAST32, PRIiFAST64
    • PRIo8, PRIo16, PRIo32, PRIo64, PRIoMAX, PRIoPTR, PRIoLEAST8, PRIoLEAST16, PRIoLEAST32, PRIoLEAST64, PRIoFAST8, PRIoFAST16, PRIoFAST32, PRIoFAST64
    • PRIu8, PRIu16, PRIu32, PRIu64, PRIuMAX, PRIuPTR, PRIuLEAST8, PRIuLEAST16, PRIuLEAST32, PRIuLEAST64, PRIuFAST8, PRIuFAST16, PRIuFAST32, PRIuFAST64
    • PRIx8, PRIx16, PRIx32, PRIx64, PRIxMAX, PRIxPTR, PRIxLEAST8, PRIxLEAST16, PRIxLEAST32, PRIxLEAST64, PRIxFAST8, PRIxFAST16, PRIxFAST32, PRIxFAST64
    • PRIX8, PRIX16, PRIX32, PRIX64, PRIXMAX, PRIXPTR, PRIXLEAST8, PRIXLEAST16, PRIXLEAST32, PRIXLEAST64, PRIXFAST8, PRIXFAST16, PRIXFAST32, PRIXFAST64
    • SCNd8, SCNd16, SCNd32, SCNd64, SCNdMAX, SCNdPTR, SCNdLEAST8, SCNdLEAST16, SCNdLEAST32, SCNdLEAST64, SCNdFAST8, SCNdFAST16, SCNdFAST32, SCNdFAST64
    • SCNi8, SCNi16, SCNi32, SCNi64, SCNiMAX, SCNiPTR, SCNiLEAST8, SCNiLEAST16, SCNiLEAST32, SCNiLEAST64, SCNiFAST8, SCNiFAST16, SCNiFAST32, SCNiFAST64
    • SCNo8, SCNo16, SCNo32, SCNo64, SCNoMAX, SCNoPTR, SCNoLEAST8, SCNoLEAST16, SCNoLEAST32, SCNoLEAST64, SCNoFAST8, SCNoFAST16, SCNoFAST32, SCNoFAST64
    • SCNu8, SCNu16, SCNu32, SCNu64, SCNuMAX, SCNuPTR, SCNuLEAST8, SCNuLEAST16, SCNuLEAST32, SCNuLEAST64, SCNuFAST8, SCNuFAST16, SCNuFAST32, SCNuFAST64
    • SCNx8, SCNx16, SCNx32, SCNx64, SCNxMAX, SCNxPTR, SCNxLEAST8, SCNxLEAST16, SCNxLEAST32, SCNxLEAST64, SCNxFAST8, SCNxFAST16, SCNxFAST32, SCNxFAST64
    • SCNX8, SCNX16, SCNX32, SCNX64, SCNXMAX, SCNXPTR, SCNXLEAST8, SCNXLEAST16, SCNXLEAST32, SCNXLEAST64, SCNXFAST8, SCNXFAST16, SCNXFAST32, SCNXFAST64
    • imaxabs, imaxdiv, strtoimax, strtoumax, wcstoimax, wcstoumax
  • ctype.h
    • isblank
  • wctype.h
    • iswblank
  • float.h
    • DECIMAL_DIG, FLT_EVAL_METHOD
  • stdarg.h
    • va_copy
  • stdbool.h
    • bool, true, false, __bool_true_false_are_defined
  • stdio.h
    • vscanf, vfscanf, vsscanf
  • stdlib.h
    • atoll, strtof, strtold, strtoll, strtoull
  • wchar.h
    • vwscanf, vfwscanf, vswscanf, wcstof, wcstold, wcstoll, wcstoull

We know that this is not complete support for the C99 library functions. To the best of our understanding, the missing pieces are these:

  • The tgmath.h header is missing. C compiler support is needed for this header.
    • Note that the ctgmath header was added—this is possible because that header does not require the tgmath.h header—only the ccomplex and cmath headers.
  • The uchar.h header is missing. This is from the C Unicode TR.
  • Several format specifiers in the printf family are not yet supported.
  • The snprintf and snwprintf functions are missing from stdio.h and wchar.h.

I hope you find this information useful. We did all that we had time for, while trying to prioritize those functions we thought most important.

Pat Brenner, Visual C++ Libraries Development Team

  • It's great to see progress on C++03 conformance being made here.

  • Despite the order of the years, C++98/03 incorporated the C89 Standard Library by reference, while C++11 incorporated the C99 Standard Library by reference. Remember, C++03 didn't even have long long. If you have a copy of C++03, this is 1.2 [intro.refs]/2: "The library described in clause 7 of ISO/IEC 9899:1990 and clause 7 of ISO/IEC 9899/Amd.1:1995 is hereinafter called the Standard C Library. 1)" "1) With the qualifications noted in clauses 17 through 27, and in C.2, the Standard C library is a subset of the Standard C++ library."

  • Its Very Good Details , thanks for Info

    Cheers

  • Finally :) we can build C99 without mingw/Cygwin. Thanks guys!

  • @STL, thank you so much for writing this blog post! I don't have words to describe my feelings.. C99 support is like a touch to the quick, for many of the VS enthusiast. For the past decade, we were missing it. Especially when collaborating in the code, which is meant to target multiple platforms.

    I have been following your blogs for a long time. And I am pretty confident that if something is on your roadmap even with least priority, I consider it done.. Please do tell:

    Would those "remaining pieces", especially uchar.h be implemented in VS2013 as well? If not VS2013, would you guys consider it in future OR let the others call it half-baked C99 support after a decade! :-)

  • Improving C99 support is a step in the right direction and very much appreciated. At least on paper, Visual C++ 2013 might be enough to continue subscribing to MSDN and postpone jumping to mingw and/or clang. It is very important to be able to leverage C99 open source projects right now.

  • I"m glad Microsoft changed their mind and finally updated Visual Studio's C99 support. I was under the impression they weren't working on it due to lack of customer demand.

  • About freaking time! Great news anyways.

  • @Wesley Robb

    really? as in all those <sys/*.h> are will also be available?

  • C99 is now how old, and VC still cannot compile the full standard test suit

    C++03 is somewhat better, C++11

    how is the standard template library managing to hold up

  • Nate: Pat Brenner, who usually works on MFC, wrote this post and did the extensive work to integrate Dinkumware's C99 <meow.h> machinery into our CRT. (James McNellis, our CRT maintainer, was working on other CRT stuff.) That integration was nontrivial - unlike VC's STL, VC's C89 CRT was not licensed from Dinkumware, it was written by MS in the mists of time. (Seriously, some of the internal comments are tagged with dates that are as old as I am.) My role here was much smaller - after updating the STL for alias templates and deleted functions, I integrated Dinkumware's <cmeow> machinery.

    Unfortunately, we won't have time to add uchar.h, or tgmath.h with its associated compiler magic, to 2013 RTM. We're shipping this calendar year, Preview's a month old, and we really have to stop adding new features to the product. It may be possible to sneak in snprintf() and/or C99 format specifiers as "bug fixes", but you should assume that this will NOT happen for RTM.

    <uchar.h>/<cuchar> are required by C++11 and are on our radar for post-2013-RTM. The same goes for snprintf() and the C99 format specifiers. <tgmath.h> and its associated compiler magic are special and I don't know our plans for them (as Pat's post explained, C++ has overloading/templates and doesn't need C compiler magic).

  • @STL

    > Despite the order of the years, C++98/03 incorporated the C89 Standard Library by reference

    Ah, yes. My fact checking only went as far as seeing C99 referenced in 1.2 [intro.refs]/1, and since everywhere else we've all been using C99 library functions for ages it seemed right that the C99 library was part of C++03.

  • @Seth: FYI, C++03 was only a minor bug fix release over C++98.

  • @STL, thanks for the post.

    Do we have something comparable with GCC's --std switch?

    I believe that MS supporting a newer standard necessitates the breaking of older code.

    I guess I'm spoiled by having the experience of using compilers from more than just one vendor. With GCC, for example you can add −std=c89 to avoid breaking your bit rot.

    Please provide this option in IDE and command-line in your ongoing efforts.

  • Methews: This isn't my post, I'm just commenting here! :->

    In general, VC's C compiler/Standard Library and C++ compiler/Standard Library don't provide options to select previous Standards. The compilers and the CRT don't usually contain major source breaking changes (ignoring simple stuff, like CRT ::atoll() clashing with users who defined their own), so targeting newer Standards isn't especially problematic. (There are isolated exceptions, like /Zc:strictStrings in VS 2013 RTM.) As for the STL, which I maintain and which regularly contains source breaking changes, the lack of a C++98/03 option is very much intentional.

    As I like to say, Modes Are Evil. Having one codebase provide both C++98/03 and C++11/14 modes increases maintenance cost. It also leads to user headaches (consider what happens if users try to link code compiled with different modes). Targeting the latest Standard/Working Paper allows us to move faster (i.e. implement more features and fix more bugs) and prevents mode-mixing headaches. The cost, of course, is that users have to fix their code to conform to the latest Standardese.

    For example, std::set experienced a major breaking change between C++03 and C++11 - its iterator effectively became a synonym for const_iterator. This improved safety (modifying set keys in order-changing ways triggers undefined behavior and corrupts the data structure) and consistency (map keys have always been const), but also broke lots of code. As it turns out, many people (including VS's own codebase) were modifying set keys in order-irrelevant ways (usually changing data members that didn't participate in the ordering). When this happened, we fixed up VS's codebase (I had to file a half-dozen bugs across the product) and then unconditionally enforced set immutability. In this case and many others, providing a mode might have been tempting in the short term, but I strongly believe that modes are profoundly damaging in the long term.

Page 1 of 2 (26 items) 12