JavaScript is required to for searching.
Skip Navigation Links
Exit Print View
Oracle Solaris Studio 12.2: C User's Guide
search filter icon
search icon

Document Information

Preface

1.  Introduction to the C Compiler

2.  C-Compiler Implementation-Specific Information

3.  Parallelizing C Code

4.  lint Source Code Checker

5.  Type-Based Alias Analysis

6.  Transitioning to ISO C

6.1 Basic Modes

6.1.1 -Xc

6.1.2 -Xa

6.1.3 -Xt

6.1.4 -Xs

6.2 A Mixture of Old- and New-Style Functions

6.2.1 Writing New Code

6.2.2 Updating Existing Code

6.2.3 Mixing Considerations

6.3 Functions With Varying Arguments

6.4 Promotions: Unsigned Versus Value Preserving

6.4.1 Background

6.4.2 Compilation Behavior

6.4.3 First Example: The Use of a Cast

6.4.4 Bit-fields

6.4.5 Second Example: Same Result

6.4.6 Integral Constants

6.4.7 Third Example: Integral Constants

6.5 Tokenization and Preprocessing

6.5.1 ISO C Translation Phases

6.5.2 Old C Translation Phases

6.5.3 Logical Source Lines

6.5.4 Macro Replacement

6.5.5 Using Strings

6.5.6 Token Pasting

6.6 const and volatile

6.6.1 Types, Only for lvalue

6.6.2 Type Qualifiers in Derived Types

6.6.3 const Means readonly

6.6.4 Examples of const Usage

6.6.5 volatile Means Exact Semantics

6.6.6 Examples of volatile Usage

6.7 Multibyte Characters and Wide Characters

6.7.1 Asian Languages Require Multibyte Characters

6.7.2 Encoding Variations

6.7.3 Wide Characters

6.7.4 Conversion Functions

6.7.5 C Language Features

6.8 Standard Headers and Reserved Names

6.8.1 Standard Headers

6.8.2 Names Reserved for Implementation Use

6.8.3 Names Reserved for Expansion

6.8.4 Names Safe to Use

6.9 Internationalization

6.9.1 Locales

6.9.2 The setlocale() Function

6.9.3 Changed Functions

6.9.4 New Functions

6.10 Grouping and Evaluation in Expressions

6.10.1 Definitions

6.10.2 The K&R C Rearrangement License

6.10.3 The ISO C Rules

6.10.4 The Parentheses

6.10.5 The As If Rule

6.11 Incomplete Types

6.11.1 Types

6.11.2 Completing Incomplete Types

6.11.3 Declarations

6.11.4 Expressions

6.11.5 Justification

6.11.6 Examples

6.12 Compatible and Composite Types

6.12.1 Multiple Declarations

6.12.2 Separate Compilation Compatibility

6.12.3 Single Compilation Compatibility

6.12.4 Compatible Pointer Types

6.12.5 Compatible Array Types

6.12.6 Compatible Function Types

6.12.7 Special Cases

6.12.8 Composite Types

7.  Converting Applications for a 64-Bit Environment

8.  cscope: Interactively Examining a C Program

A.  Compiler Options Grouped by Functionality

B.  C Compiler Options Reference

C.  Implementation-Defined ISO/IEC C99 Behavior

D.  Supported Features of C99

E.  Implementation-Defined ISO/IEC C90 Behavior

F.  ISO C Data Representations

G.  Performance Tuning

H.  The Differences Between K&R Solaris Studio C and Solaris Studio ISO C

Index

6.3 Functions With Varying Arguments

In previous implementations, you could not specify the parameter types that a function expected, but ISO C encourages you to use prototypes to do just that. To support functions such as printf(), the syntax for prototypes includes a special ellipsis () terminator. Because an implementation might need to do unusual things to handle a varying number of arguments, ISO C requires that all declarations and the definition of such a function include the ellipsis terminator.

Since there are no names for the “” part of the parameters, a special set of macros contained in stdarg.h gives the function access to these arguments. Earlier versions of such functions had to use similar macros contained in varargs.h.

Let us assume that the function we wish to write is an error handler called errmsg() that returns void, and whose only fixed parameter is an int that specifies details about the error message. This parameter can be followed by a file name, a line number, or both, and these are followed by format and arguments, similar to those of printf(), that specify the text of the error message.

To allow our example to compile with earlier compilers, we make extensive use of the macro __STDC__ which is defined only for ISO C compilation systems. Thus, the function’s declaration in the appropriate header file is:

#ifdef __STDC__
    void errmsg(int code, ...);
#else
    void errmsg();
#endif

The file that contains the definition of errmsg() is where the old and new styles can get complex. First, the header to include depends on the compilation system:

#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include <stdio.h>

stdio.h is included because we call fprintf() and vfprintf() later.

Next comes the definition for the function. The identifiers va_alist and va_dcl are part of the old-style varargs.h interface.

void
#ifdef __STDC__
errmsg(int code, ...)
#else
errmsg(va_alist) va_dcl /* Note: no semicolon! */
#endif
{
   /* more detail below */
}

Since the old-style variable argument mechanism did not allow us to specify any fixed parameters, we must arrange for them to be accessed before the varying portion. Also, due to the lack of a name for the “” part of the parameters, the new va_start() macro has a second argument—the name of the parameter that comes just before the “” terminator.

As an extension, Solaris Studio ISO C allows functions to be declared and defined with no fixed parameters, as in:

int f(...);

For such functions, va_start() should be invoked with an empty second argument, as in:

va_start(ap,)

The following is the body of the function:

{
    va_list ap;
    char *fmt;
#ifdef __STDC__
    va_start(ap, code);
#else
    int code;
    va_start(ap);
    /* extract the fixed argument */
    code = va_arg(ap, int);
#endif
    if (code & FILENAME)
        (void)fprintf(stderr, "\"%s\": ", va_arg(ap, char *));
    if (code & LINENUMBER)
        (void)fprintf(stderr, "%d: ", va_arg(ap, int));
    if (code & WARNING)
        (void)fputs("warning: ", stderr);
    fmt = va_arg(ap, char *);
    (void)vfprintf(stderr, fmt, ap);
    va_end(ap);
}

Both the va_arg() and va_end() macros work the same for the old-style and ISO C versions. Because va_arg() changes the value of ap, the call to vfprintf() cannot be:

(void)vfprintf(stderr, va_arg(ap, char *), ap);

The definitions for the macros FILENAME, LINENUMBER, and WARNING are presumably contained in the same header as the declaration of errmsg().

A sample call to errmsg() could be:

errmsg(FILENAME, "<command line>", "cannot open: %s\n",
argv[optind]);