C User's Guide |
Sun ANSI/ISO C Compiler-Specific Information
The Sun ANSI/ISO C compiler is compatible with the C language described in the American National Standard for Programming Language--C, ANSI/ISO 9899-1990. This chapter documents those areas specific to the Sun ANSI/ISO C compiler and is organized into the following sections:
- Environment Variables
- Global Behavior: Value Versus unsigned Preserving
- Keywords
- long long Data Type
- Constants
- Include Files
- Nonstandard Floating Point
- Preprocessing Directives and Names
Environment Variables
TMPDIR
cc
normally creates temporary files in the directory/tmp
. You can specify another directory by setting the environment variableTMPDIR
to the directory of your choice. However, ifTMPDIR
is not a valid directory,cc
uses/tmp
. The-xtemp
option has precedence over theTMPDIR
environment variable.If you use a Bourne shell, type:
$
TMPDIR=
dir; export TMPDIR
If you use a C shell, type:
%
setenv TMPDIR
dir
SUNPRO_SB_INIT_FILE_NAME
The
absolute path name of the directory containing the
.sbinit
(5) file. This variable is used only if the-xsb
or-xsbfast
flag is used.
PARALLEL
(SPARC) Specifies the number of processors available to the program for multiprocessor execution. If the target machine has multiple processors, the threads can map to independent processors. Running the program leads to the creation of two threads that execute the parallelized portions of the program.
SUNW_MP_THR_IDLE
Controls the status of each thread after it finishes its share of a parallel job. You can set
SUNW_MP_THR_IDLE
to eitherspin
orsleep
[
ns
|nms]
. The default isspin
, which means the thread goes spin-waiting. The other choice,sleep
[
ns
|nms]
puts the thread to sleep after spin-waiting for n units. The wait can be seconds (s
is the default unit) or milliseconds (ms
) where1s
means one second,10
ms
means ten milliseconds. If a new job arrives before n units is reached, the thread stops spin-waiting and starts doing the new job. IfSUNW_MP_THR_IDLE
contains an illegal value or is not set,spin
is used as the default.Global Behavior: Value Versus
unsigned
PreservingA program that depends on
unsigned
preserving arithmetic conversions behaves differently. This is considered to be the most serious change made by ANSI/ISO C.In the first edition of K&R, The C Programming Language (Prentice-Hall, 1978),
unsigned
specified exactly one type; there were nounsigned chars
,unsigned shorts
, orunsigned longs
, but most C compilers added these very soon thereafter.In K&R C compilers, the
unsigned
preserving rule is used for promotions: when anunsigned
type needs to be widened, it is widened to anunsigned
type; when anunsigned
type mixes with asigned
type, the result is anunsigned
type.The other rule, specified by ANSI/ISO C, came to be called "value preserving," in which the result type depends on the relative sizes of the operand types. When an
unsigned
char
orunsigned
short
is widened, the result type isint
if anint
is large enough to represent all the values of the smaller type. Otherwise, the result type isunsigned
int
. The value preserving rule produces the least surprise arithmetic result for most expressions.Only in the
-Xt
and-Xs
modes does the compiler use theunsigned
preserving promotions; in the other modes,-Xc
and-Xa
, the value preserving promotion rules are used. When the -xtransition
option is used, the compiler warns about each expression whose behavior might depend on the promotion rules used.Keywords
asm
KeywordThe
_asm
keyword is a synonym for theasm
keyword.
asm
is available under all compilation modes except the-Xc
mode.Theasm
statement has the form:
asm("string");where string is a valid assembly language statement. The
asm
statements must appear within function bodies.
_Restrict
KeywordFor a compiler to effectively perform parallel execution of a loop, it needs to determine if certain
lvalues
designate distinct regions of storage. Aliases arelvalues
whose regions of storage are not distinct. Determining if two pointers to objects are aliases is a difficult and time-consuming process because it could require analysis of the entire program.For example, consider the functions
vsq()
:
void vsq(int n, double * a, double * b){int i;for (i=0; i<n; i++) b[i] = a[i] * a[i];}
The compiler can parallelize the execution of the different iterations of the loops if it knows that pointers a and b access different objects. If there is an overlap in objects accessed through pointers a and b then it would be unsafe for the compiler to execute the loops in parallel. At compile time, the compiler does not know if the objects accessed by a and b overlap by simply analyzing the function
vsq
(); the compiler may need to analyze the whole program to get this information.Restricted pointers are used to specify pointers which designate distinct objects so that the compiler can perform pointer alias analysis. To support restricted pointers, the keyword
_Restrict
is recognized by the Sun ANSI/ISO C compiler as an extension. Below is an example of declaring function parameters ofvsq
() as restricted pointers:
void vsq(int n, double * _Restrict a, double * _Restrict b)
Pointers
a
andb
are declared as restricted pointers, so the compiler knows that the regions of storage pointed to by a and b are distinct. With this alias information, the compiler is able to parallelize the loop.The
_Restrict
keyword is a type qualifier, likevolatile
, and it qualifies pointer types only._Restrict
is recognized as a keyword only for compilation modes-Xa
(default) and-Xt
. For these two modes, the compiler defines the macro__RESTRICT
to enable users write portable code with restricted pointers.The compiler defines the macro
__RESTRICT
to enable users to write portable code with restricted pointers. For example, the following code works on the Sun ANSI/ISO C compiler in all compilation modes, and should work on other compilers which do not support restricted pointers:
#ifdef __RESTRICT#define restrict _Restrict#else#define restrict#endifvoid vsq(int n, double * restrict a, double * restrict b){int i;for (i=0; i<n; i++) b[i] = a[i] * a[i];}
If restricted pointers become a part of the ANSI/ISO C Standard, it is likely that
restrict
will be the keyword. Users may want to write code with restricted pointers using:
#define restrict _Restrict
as in
vsq()
because this way there will be minimal changes shouldrestrict
become a keyword in the ANSI/ISO C Standard. The Sun ANSI/ISO C compiler uses_Restrict
as the keyword because it is in the implementor's name space, so there is no conflict with identifiers in the user's name space.There are situations where a user may not want to change the source code. One can specify pointer-valued function parameters to be treated as restricted pointers with the command-line option
-xrestrict
; refer to -xrestrict=f for details.If a function list is specified, pointer parameters in the specified functions are treated as restricted; otherwise, all pointer parameters in the entire C file are treated as restricted. For example,
-xrestrict=vsq
would qualify the pointersa
andb
given in the example with the keyword_Restrict
.It is critical that
_Restrict
be used correctly. If pointers qualified as restricted pointers point to objects which are not distinct, loops may be incorrectly parallelized, resulting in undefined behavior. For example, assume that pointersa
andb
of functionvsq()
point to objects which overlap, such thatb[i]
anda[i+1]
are the same object. Ifa
andb
are not declared as restricted pointers, the loops will be executed serially. Ifa
andb
are incorrectly qualified as restricted pointers, the compiler may parallelize the execution of the loops; this is not safe, becauseb[i+1]
should only be computed afterb[i]
has been computed.
long long
Data TypeThe Sun ANSI/ISO C compiler includes the data types
long long
, andunsigned
long long
, which are similar to the data typelong
.long long
can store 64 bits of information;long
can store 32 bits of information.long long
is not available in-Xc
mode.Printing
long long
Data TypesTo print or scan
long long
data types, prefix the conversion specifier with the letters "ll." For example, to printllvar
, a variable oflong long
data type, in signed decimal format, use:
printf("%lld\n", llvar);Usual Arithmetic Conversions
Some binary operators convert the types of their operands to yield a common type, which is also the type of the result. These are called the usual arithmetic conversions:
- If either operand is type
long double
, the other operand is converted tolong double
.- Otherwise, if either operand has type
double
, the other operand is converted todouble
.- Otherwise, if either operand has type
float
, the other operand is converted tofloat
.- Otherwise, the integral promotions are performed on both operands. Then, these rules are applied:
- If either operand has type
unsigned
long long
int
, the other operator is converted tounsigned
long
long
int
.- If either operand has type
long
long
int
, the other operator is converted tolong
long
int
.- If either operand has type
unsigned
long
int
, the other operand is converted tounsigned
long
int
.- Otherwise, if one operand has type
long
int
and the other has typeunsigned
int,
both operands are converted tounsigned
long
int
.- Otherwise, if either operand has type
long
int,
the other operand is converted tolong
int
.- Otherwise, if either operand has type
unsigned
int
, the other operand is converted tounsigned
int
.- Otherwise, both operands have type
int
.Constants
This section contains information related to constants that is specific to the Sun ANSI/ISO C compiler.
Integral Constants
Decimal, octal, and hexadecimal integral constants can be suffixed to indicate type, as shown in the following table.
TABLE 3-1 Data Type Suffixes u
orU
unsigned
l
orL
long
ll
orLL
long long
1lu
,LU
,Lu
,lU, ul, uL, Ul, or UL
unsigned long
llu
,LLU
,LLu
,llU, ull, ULL, uLL, Ull
unsigned long long
1
1 The long
long
andunsigned
long
lo
ng are not available in-Xc
mode.
When assigning types to unsuffixed constants, the compiler uses the first of this list in which the value can be represented, depending on the size of the constant:
int
long int
unsigned long int
long long int
unsigned long long int
Character Constants
A multiple-character constant that is not an escape sequence has a value derived from the numeric values of each character. For example, the constant
'123'
has a value of:
0
'3'
'2'
'1'
With the
-Xs
option and in other, non-ANSI/ISO versions of C, the value is:
0
'1'
'2'
'3'
Include Files
To include any of the standard header files supplied with the C compilation system, use this format:
#include <stdio.h>
The angle brackets
(<>
) cause the preprocessor to search for the header file in the standard place for header files on your system, usually the/usr/include
directory.The format is different for header files that you have stored in your own directories:
#include "header.h"
The quotation marks (
" "
) cause the preprocessor to search forheader.h
first in the directory of the file containing the#include
line.If your header file is not in the same directory as the source files that include it, specify the path of the directory in which it is stored with the
-I
option tocc
. Suppose, for instance, that you have included bothstdio.h
andheader.h
in the source filemycode.c
:
#include <stdio.h>#include "header.h"
Suppose further that
header.h
is stored in the directory../defs
. The command:
%
cc -I../defs mycode.c
directs the preprocessor to search for
header.h
first in the directory containingmycode.c
, then in the directory../defs
, and finally in the standard place. It also directs the preprocessor to search forstdio.h
first in../defs
, then in the standard place. The difference is that the current directory is searched only for header files whose names you have enclosed in quotation marks.You can specify the
-I
option more than once on thecc
command-line. The preprocessor searches the specified directories in the order they appear. You can specify multiple options tocc
on the same command-line:
%
cc -o prog -I../defs mycode.c
Nonstandard Floating Point
IEEE 754 floating-point default arithmetic is "nonstop." Underflows are "gradual." The following is a summary, see the Numerical Computation Guide for details.
Nonstop means that execution does not halt on occurrences like division by zero, floating-point overflow, or invalid operation exceptions. For example, consider the following, where
x
is zero andy
is positive:By default,
z
is set to the value+Inf
, and execution continues. With the-fnonstd
option, however, this code causes an exit, such as a core dump.Here is how gradual underflow works. Suppose you have the following code:
x = 10;for (i = 0; i < LARGE_NUMBER; i++)x = x / 10;
The first time through the loop,
x
is set to1
; the second time through, to0.1
; the third time through, to0.01
; and so on. Eventually,x
reaches the lower limit of the machine's capacity to represent its value. What happens the next time the loop runs?Let's say that the smallest number characterizable is
1.234567e-38
The next time the loop runs, the number is modified by "stealing" from the mantissa and "giving" to the exponent so the new value is
1.23456e-39
and, subsequently,1.2345e-40
and so on. This is known as "gradual underflow," which is the default behavior. In nonstandard mode, none of this "stealing" takes place; typically,x
is simply set to zero.Preprocessing Directives and Names
This section describes assertions, pragmas, and predefined names.
Assertions
A line of the form:
#assert predicate(
token-sequence)
associates the token-sequence with the predicate in the assertion name space (separate from the space used for macro definitions). The predicate must be an identifier token.
#assert predicate
asserts that predicate exists, but does not associate any token sequence with it.
The compiler provides the following predefined predicates by default (not in
-Xc
mode):
#assert system (unix)#assert machine (sparc)(SPARC)#assert machine (i386)(Intel)#assert cpu (sparc)(SPARC)#assert cpu (i386)(Intel)
lint
provides the following predefinition predicate by default (not in-Xc
mode):
#assert lint (on)
Any assertion may be removed by using
#unassert
, which uses the same syntax asassert
. Using#unassert
with no argument deletes all assertions on the predicate; specifying an assertion deletes only that assertion.An assertion may be tested in a
#if
statement with the following syntax:
#if #predicate(
non-empty token-list)
For example, the predefined predicate
system
can be tested with the following line:
#if #system(unix)
Pragmas
Preprocessing lines of the form:
#pragma pp-tokens
specify implementation-defined actions.
The following
#pragma
s are recognized by the compilation system. The compiler ignores unrecognized pragmas. Using the-v
option will give a warning on unrecognized pragmas.
#pragma
align
integer(
variable[, variable])
The align pragma makes all the mentioned variables memory aligned to integer bytes, overriding the default. The following limitations apply:
- The integer value must be a power of 2 between 1 and 128; valid values are: 1, 2, 4, 8, 16, 32, 64, and 128.
- variable is a global or static variable; it cannot be an automatic variable.
- If the specified alignment is smaller than the default, the default is used.
- The pragma line must appear before the declaration of the variables which it mentions; otherwise, it is ignored.
- Any variable that is mentioned but not declared in the text following the pragma line is ignored. For example:
#pragma align 64 (aninteger, astring, astruct)int aninteger;static char astring[256];struct astruct{int a; char *b;};
#pragma
does_not_read_global_data
(
funcname[,
funcname])
This pragma asserts that the specified list of routines do not read global data directly or indirectly. This allows for better optimization of code around calls to such routines. In particular, assignment statements or stores could be moved around such calls.
This pragma is permitted only after the prototype for the specified functions are declared. If the assertion about global access is not true, then the behavior of the program is undefined.
#pragma
does_not_return
(
funcname[,
funcname])
This pragma is an assertion to the compiler backend that the calls to the specified routines will not return. This allows the optimizer to perform optimizations consistent with that assumption. For example, register life-times will terminate at the call sites which in turn allows more optimizations.
If the specified function does return, then the behavior of the program is undefined.
This pragma is permitted only after the prototype for the specified functions are declared as the following example shows:
extern void exit(int);#pragma does_note_return(exit);extern void __assert(int);#pragma does_not_return(__assert);
#pragma
does_not_write_global_data
(
funcname [,
funcname])
This pragma asserts that the specified list of routines do not write global data directly or indirectly. This allows for better optimization of code around calls to such routines. In particular, assignment statements or stores could be moved around such calls.
This pragma is permitted only after the prototype for the specified functions are declared. If the assertion about global access is not true, then the behavior of the program is undefined.
#pragma
error_messages
(on
|off
|default,
tag... tag)
The error message pragma provides control within the source program over the messages issued by the C compiler and lint. For the C compiler, the pragma has an effect on warning messages only. The -w option of the C compiler overrides this pragma by suppressing all warning messages.
#pragma
error_messages
(on,
tag... tag)
- The
on
option ends the scope of any preceding#pragma
error_messages
option, such as the off option, and overrides the effect of the-erroff
option.#pragma
error_messages
(off,
tag... tag)
- The
off
option prevents the C compiler or the lint program from issuing the given messages beginning with the token specified in the pragma. The scope of the pragma for any specified error message remains in effect until overridden by another#pragma
error_messages
, or the end of compilation.#pragma
error_messages
(default,
tag... tag)
- The
default
option ends the scope of any preceding#pragma
error_messages
directive for the specified tags.#
pragma
fini
(
f1[,
f2...,
fn])
Causes the implementation to call functions f1 to fn (finalization functions) after it calls
main()
routine. Such functions are expected to be of typevoid
and to accept no arguments, and are called either when a program terminates under program control or when the containing shared object is removed from memory. As with "initialization functions," finalization functions are executed in the order processed by the link editors.
#pragma ident
stringPlaces string in the
.comment
section of the executable.
#pragma init
(
f1[,
f2...,
fn])
Causes the implementation to call functions f1 to fn (initialization functions) before it calls
main()
. Such functions are expected to be of type void and to accept no arguments, and are called while constructing the memory image of the program at the start of execution. In the case of initializers in a shared object, they are executed during the operation that brings the shared object into memory, either program start-up or some dynamic loading operation, such asdlopen()
. The only ordering of calls to initialization functions is the order in which they were processed by the link editors, both static and dynamic.
#pragma
[no_]inline
(
funcname[,
funcname])
This pragma controls the inlining of routine names listed in the argument of the pragma. The scope of this pragma is over the entire file. Only global inlining control is allowed, call-site specific control is not permitted by this pragma.
If you use
#pragma inline
, it provides a suggestion to the compiler to inline the calls in the current file that match the list of routines listed in the pragma. This suggestion may be ignored under certain cases. For example, the suggestion is ignored when the body of the function is in a different module and the crossfile option is not used.If you use
#pragma no_inline
, it provides a suggestion to the compiler to not inline the calls in the current file that match the list of routines listed in the pragma.Both
#pragma
inline
and#pragma
no_inline
are permitted only after the prototype for the specified functions are declared as the following example shows:
static void foo(int);static int bar(int, char *);#pragma inline(foo, bar)
#pragma int_to_unsigned
(
funcname)
For a function that returns a type of
unsigned
, in-Xt
or-Xs
mode, changes the function return to be of typeint
.(SPARC)
#pragma MP serial_loop
Refer to Serial Pragmas for details.
(SPARC)
#pragma MP serial_loop_nested
Refer to Serial Pragmas for details.
(SPARC)
#pragma MP taskloop
Refer to Parallel Pragma for details.
(SPARC)
#pragma nomemorydepend
This pragma specifies that for any iteration of a loop, there are no memory dependences. That is, within any iteration of a loop there are no references to the same memory. This pragma will permit the compiler (pipeliner) to schedule instructions, more effectively, within a single iteration of a loop. If any memory dependences exist within any iteration of a loop, the results of executing the program are undefined. The pragma applies to the next
for
loop within the current block. The compiler takes advantage of this information at optimization level of 3 or above.(SPARC)
#pragma no_side_effect(
funcname[,
funcname])
funcname specifies the name of a function within the current translation unit. The function must be declared prior to the pragma. The pragma must be specified prior to the function's definition. For the named function, funcname, the pragma declares that the function has no side effects of any kind. This means that funcname returns a result value that depends only on the passed arguments. In addition, funcname and any called descendants:
- Do not access for reading or writing any part of the program state visible in the caller at the point of the call.
- Do not perform I/O.
- Do not change any part of the program state not visible at the point of the call.
The compiler can use this information when doing optimizations using the function. If the function does have side effects, the results of executing a program which calls this function are undefined. The compiler takes advantage of this information at optimization level of 3 or above.
#pragma
opt
level(
funcname[,
funcname])
The value of level specifies the optimization level for the funcname subprograms. You can assign opt levels zero, one, two three, four, and five. You can turn off optimization by setting level to
0
. The funcname subprograms must be prototyped prior to the pragma.The level of optimization for any function listed in the pragma is reduced to the value of
-xmaxopt
. The pragma is ignored when-xmaxopt=off
.
#pragma
pack(
n)
Use
#pragma
pack(
n)
, to affect member packing of a structure. By default, members of a structure are aligned on their natural boundaries; one byte for a char, two bytes for a short, four bytes for an integer etc. If n is present, it must be a power of 2 specifying the strictest natural alignment for any structure member. Zero is not accepted.You can use
#pragma
pack(
n)
to specify an alignment boundary for a structure member. For example,#pragma
pack(2)
aligns int, long, long long, float, double, long double, and pointers on two byte boundaries instead of their natural alignment boundaries.If n is the same or greater than the strictest alignment on your platform, (four on Intel, eight on SPARC v8, and 16 on SPARC v9), the directive has the effect of natural alignment. Also, if n is omitted, member alignment reverts to the natural alignment boundaries.
The
#pragma
pack(
n)
directive applies to all structure definitions which follow it until the next pack directive. If the same structure is defined in different translation units with different packing, your program may fail in unpredictable ways. In particular, you should not use#pragma
pack(
n)
prior to including a header that defines the interface of a precompiled library. The recommended usage of#pragma
pack(
n)
is to place it in your program code immediately before any structure to be packed. Follow the packed structure immediately with#pragma
pack()
.
Note If you use#pragma
pack
to align struct members on boundaries other than their natural boundaries, accessing these fields may lead to a bus error on SPARC. See -xmemalign=ab, for the optimal way to compile such programs.
(SPARC)
#pragma pipeloop(
n)
This pragma accepts a positive constant integer value, or 0, for the argument n. This pragma specifies that a loop is pipelinable and the minimum dependence distance of the loop-carried dependence is n. If the distance is 0, then the loop is effectively a Fortran-style
doall
loop and should be pipelined on the target processors. If the distance is greater than 0, then the compiler (pipeliner) will only try to pipeline n successive iterations. The pragma applies to the nextfor
loop within the current block. The compiler takes advantage of this information at optimization level of 3 or above.
#pragma
rarely_called(
funcname[,
funcname])
This pragma provides a hint to the compiler backend that the specified functions are called infrequently. This allows the compiler to perform profile-feedback style optimizations on the call-sites of such routines without the overhead of a profile-collections phase. Since this pragma is a suggestion, the compiler optimizer may not perform any optimizations based on this pragma.
The
#pragma
rarely_called
preprocessor directive is only permitted after the prototype for the specified functions are declares. The following is an example of#pragma
rarely_called
:
extern void error (char *message);#pragma rarely_called(error);
#pragma redefine_extname
old_extname new_extnameThis pragma causes every externally defined occurrence of the name old_extname in the object code to be replaced by new_extname. As a result, the linker only sees the name new_extname at link time. If
#pragma
redefine_extname
is encountered after the first use of old_extname, as a function definition, an initializer, or an expression, the effect is undefined. (This pragma is not supported in-Xs
mode.)When
#pragma
redefine_extname
is available, the compiler provides a definition of the predefined macroPRAGMA_REDEFINE_EXTNAME
which lets you write portable code that works both with and without#pragma
redefine_extname
.The purpose of
#pragma
redefine_extname
is to allow an efficient means of redefining a function interface when the name of the function cannot be changed. For example, when the original function definition must be maintained in a library, for compatibility with existing programs, along with a new definition of the same function for use by new programs. This can be accomplished by adding the new function definition to the library by a new name. Consequently, the header file that declares the function uses#pragma
redefine_extname
so that all of the uses of the function are linked with the new definition of that function.
#pragma
returns_new_memory
(
funcname[,
funcname])
This pragma asserts that the return value of the specified functions does not alias with any memory at the call site. In effect, this call returns a new memory location. This informations allows the optimizer to better track pointer values and clarify memory location. This results in improved scheduling, pipelining, and parallelization of loops. However, if the assertion is false, the behavior of the program is undefined.
This pragma is permitted only after the prototype for the specified functions are declared as the following example shows:
void *malloc(unsigned);#pragma returns_new_memory(malloc);
#pragma unknown_control_flow
(
name[,
name])
In order to describe procedures that alter the flow graphs of their callers, the C compiler provides the
#pragma unknown_control_flow
directive. Typically, this directive accompanies declarations of functions likesetjmp()
. On Sun systems, the include file<setjmp.h>
contains the following:
extern int setjmp();#pragma unkown_control_flow(setjmp);
Other functions with properties like those of
setjmp()
must be declared similarly.In principle, an optimizer that recognizes this attribute could insert the appropriate edges in the control flow graph, thus handling function calls safely in functions that call
setjmp()
, while maintaining the ability to optimize code in unaffected parts of the flow graph.(SPARC)
#pragma unroll
(
unroll_factor)
This pragma accepts a positive constant integer value for the argument unroll_factor. The pragma applies to the next
for
loop within the current block. For unroll factor other than 1, this directive serves as a suggestion to the compiler that the specified loop should be unrolled by the given factor. The compiler will, when possible, use that unroll factor. When the unroll factor value is 1, this directive serves as a command which specifies to the compiler that the loop is not to be unrolled. The compiler takes advantage of this information at optimization level of 3 or above.
#pragma weak
symbol1[=
symbol2]
Defines a weak global symbol. This pragma is used mainly in source files for building libraries. The linker does not produce an error message if it is unable to resolve a weak symbol.
#pragma weak symbol
defines symbol to be a weak symbol. The linker does not produce an error message if it does not find a definition for symbol.
#pragma weak symbol1 = symbol2
defines symbol1 to be a weak symbol, which is an alias for the symbol symbol2. This form of the pragma can only be used in the same translation unit where symbol2 is defined, either in the sourcefiles or one of its included headerfiles. Otherwise, a compilation error will result.
If your program calls but does not define symbol1, and symbol1 is a weak symbol in a library being linked, the linker uses the definition from that library. However, if your program defines its own version of symbol1, then the program's definition is used and the weak global definition of symbol1 in the library is not used. If the program directly calls symbol2, the definition from the library is used; a duplicate definition of symbol2 causes an error.
Variable Argument Lists for
#define
The C compiler accepts
#define
preprocessor directives of the following form:
#define identifier (...) replacement_list#define identifier (identifier_list, ...) replacement_list
If the identifier_list in the macro definition ends with an ellipses, it means that there will be more arguments in the invocation than there are parameters in the macro definition, excluding the ellipsis. Otherwise, the number of parameters in the macro definition, including those arguments which consist of no preprocessing tokens, matches the number of arguments. Use the identifier
__VA_ARGS__
in the replacement list of a#define
preprocessing directive which uses the ellipsis notation in its arguments. The following example demonstrates the variable argument list macro facilities.
which results in the following:
fprintf(stderr, "Flag");fprintf(stderr, "X = %d\n", x);puts("The first, second, and third items.");((x>y)?puts("x>y"):printf("x is %d but y is %d", x, y));
Predefined Data
The compiler predefines a static, constant, char array named
__func__
for every function definition. The array is initialized with the name of the function and can be used anywhere a static function scope array may be used. For example, use the array to print the name of the enclosing function.
#include <stdio.h>void the_func(void){printf("%s\n", __func__);/* ... */}
Each time the function is called, it prints
the_func
to the standard output.Predefined Names
The following identifier is predefined as an object-like macro:
TABLE 3-2 Predefined Identifier Identifier Description __STDC__
__STDC__ 1 -Xc
__STDC__ 0 -Xa, -Xt
Not defined-Xs
The compiler issues a warning if
__STDC__
is undefined (#undef __STDC__
).__STDC__
is not defined in-Xs
mode.Predefinitions (not valid in
-Xc
mode):
sun
unix
sparc
(SPARC)i386
(Intel)The following predefinitions are valid in all modes:
__sun
__unix
__SUNPRO_C=0x510
__`uname -s`_`uname -r`
(
example:__SunOS_5_7
)__sparc
(SPARC)__i386
(Intel)__BUILTIN_VA_ARG_INCR
__SVR4
__sparcv9
(-Xarch=v9
,v9a
)The compiler also predefines the object-like macro
__PRAGMA_REDEFINE_EXTNAME
to indicate that the pragma will be recognized. The following is predefined in-Xa
and-Xt
modes only:
Sun Microsystems, Inc. Copyright information. All rights reserved. Feedback |
Library | Contents | Previous | Next | Index |