C++ Migration Guide

C Library Headers

In compatibility mode, you use the standard headers from C in exactly the same way as before. The headers are in the /usr/include directory, supplied with the version of Solaris you are using.

For clarification, the headers being discussed are the 17 headers defined by the ISO C standard (ISO 9899:1990) plus its later addendum (1994):


<assert.h> <ctype.h>  <errno.h>  <float.h>  <iso646.h> <limits.h> 
<locale.h> <math.h>   <setjmp.h> <signal.h> <stdarg.h> <stdio.h>
<stdlib.h> <string.h> <time.h>   <wchar.h>  <wctype.h>

The hundreds of other headers that reside in and below the /usr/include directory are not affected by this language change because they are not part of the C language standard.

The C++ standard has changed the definition of the standard C headers.

You can include and use any of these headers in a C++ program the same as in previous versions of Sun C++, but some restrictions apply.

The C++ standard requires that the names of types, objects, and functions in these headers appear in namespace std as well as in the global namespace. This in turn means that the versions of these headers supplied with Solaris (including Solaris 7) cannot be used directly. If you compile in standard mode, you must use the versions of these headers that are supplied with the C++ 5.0 compiler. If you use the wrong headers, your program can fail to compile or link.

Just one restriction applies: Use the standard spelling for the header, not a path name. For example, write:

#include <stdio.h> // Correct

and not either of these:

#include "/usr/include/stdio.h" // Wrong #include </usr/include/stdio.h> // Wrong

The C++ standard also introduces a second version of each of the 17 standard C headers. For each header of the form <NAME.h>, there is an additional header of the form <cNAME>. That is, the trailing ".h" is dropped, and a leading "c" is added. Some examples: <cstdio>, <cstring>, <cctype>.

These headers contain the names from the original form of the header, but appear only in namespace std. An example of use according to the C++ standard is:


#include <cstdio>
int main() { 		
    printf("Hello, ");       // Error, printf unknown
    std::printf("world!\n"); // OK
}

Because the code uses <cstdio> instead of <stdio.h>, the name printf appears only in namespace std and not in the global namespace. You must either qualify the name printf, or add a using-declaration:


#include <cstdio>
using std::printf;
int main() {
    printf("Hello, ");       // OK
    std::printf("world!\n"); // OK
}

The standard C headers in /usr/include contain many declarations that are not allowed by the C standard. The declarations are there for historical reasons, primarily because Unix systems have traditionally had the extra declarations in those headers, or because other standards (like POSIX or XOPEN) require them. For continued compatibility, these extra names continue to appear in the Sun C++ versions of the <NAME.h> headers, but only in the global namespace. These extra names do not appear in the <cNAME> versions of the headers. Since these new headers have never been used in any previous program, there is no compatibility or historical issue. Consequently, you might not find the <cNAME> headers to be useful for general programming. If you want to write maximally portable standard C++ code, however, be assured that the <cNAME> headers do not contain any unportable declarations. The following example uses <stdio.h>:


#include <stdio.h>                     // stdin in global namespace
int f() { return fileno(stdin); }      // OK
int g() { return std::fileno(stdin); } // Error


#include <cstdio>                           // stdin in namespace std
int f() { return fileno(std::stdin); }      // Error
int g() { return std::fileno(std::stdin); } // Error

The following example uses <cstdio>:

Function fileno is an extra function that for compatibility continues to appear in <stdio.h>, but only in the global namespace, not in namespace std. Because it is an extra function, it does not appear in <cstdio> at all.


Note -

The C++ 5.0 version of the C standard headers is not fully compliant in all these respects on Solaris 2.5.1 or 2.6.


The C++ standard allows using both the <NAME.h> and <cNAME> versions of the standard C headers in the same compilation unit. Although you probably would not do this on purpose, it can happen when you include, for example, <cstdlib> in your own code, and some project header you use includes <stdlib.h>. On Solaris environments 2.5.1 and 2.6, this mixing does not work for some headers, particularly for the <wchar.h>/<cwchar> and <wctype.h>/<cwctype> header pairs. If you get compiler complaints about one of these headers, use the <NAME.h> version of the header in your code instead of the <cNAME> version.