![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Apex C Language Constructs The Apex C compiler accepts programs which conform to ISO/IEC 9899:1990, the 1990 version of the official standard for the C programming language. The compiler provides a limited number of extensions, mostly to simplify the task of writing header files intended to be shared by C and C++ programs. In addition, Rational recognizes that many C users must still support large programs which were written before this standard came into existence. Apex C provides a compatibility mode which causes the compiler to accept many language constructs made illegal by this standard.
The following topics are covered in this chapter:
- Extensions
- Supported Pragmas
- Compatibility Mode
- Implementation-Defined, Unspecified, and Undefined Behaviors
Extensions
- The extern linkage specifier has been extended to allow the C++ form which includes an optional language specifier. This is most commonly used to call C functions from C++ programs.
Examples:
extern "C" void foo(init); extern "C" { init bar(void); char *baz(char *); }- Variadic functions do not require any non-variable arguments, as in C++. For example,
void foo(...) { }is legal. The va_start macro in stdarg.h ignores its first argument, so it is possible to get at the arguments to one of these functions by giving a dummy (or non-existent) first argument to va_start.
- On Alpha, IRIX, and 64-bit Solaris systems, long long and unsigned long long are accepted as separate types with a size of 64-bits. On other systems, the compiler will allow the use of long long and unsigned long long in function declarations, structure definitions, and typedef definitions, but not allow any variable definitions, function definitions, or expressions that use those types. This allows code to use header files which assume that long long exists provided that no actual code makes use of long long.
- The preprocessing directives #assert and #unassert are supported. These allow for identifiers that are in the namespace of the preprocessor but not the namespace of the rest of the program. The #assert directive has two forms, either:
or
#assertidentifier
#assertidentifier
(identifier
)The #unassert directive is similar. If a # character is found within an #if or #elif directive, then it evaluates to true if the text following it was specified in a preceding #assert directive (without being in an #unassert directive), and evaluates to false otherwise. Identifiers specified in #assert directives appearing in any context other than after a # character are treated normally. For example, the following program should compile correctly and should print "Hello world" when run.
#assert foo #assert bar(quux) #define foo "Hello" #if #foo char *a = foo; #endif #if #bar(quux) char *bar = "world"; #endif #if #baz # error #endif #if #bar(xyz) # error #endif #if defined(bar) # error #endif #unassert foo #if #foo # error #endif #include <stdio.h> int main() { printf("%s %s\n", a, bar); return 0; }
- Rather than being an error, as required by the standard, the preprocessing directive #ident followed by a single string constant is silently ignored.
Supported PragmasThe following pragmas directives are recognized:
- #pragma external_name identifier [prefix] "string"
Causes the name specified by the given string to be used as the external name of the given identifier. The string must be within quotation marks. The identifier must refer to an external function or variable that has been declared but not yet defined or referenced. The function or variable may be defined following the pragma. This pragma is useful when linking with code written in other languages where the name of the thing being linked with is not a legal C identifier. If the optional word prefix is in between the identifier and the string, then an underscore ('_') will be added to the beginning of the string on systems where that is the custom. For example, on BSD-based UNIX systems, prefix will cause an underscore to be added, while on System V-based UNIX systems, prefix has no effect.
- #pragma warnings on|off|default
Allow warnings to be turned on or off. The value of default restores them to what was specified on the command line (off if the -w option was used, on otherwise).
- #pragma warn name on|off|fatal|default
Turns an individual warning on or off, or turns it into a fatal warning. The name of the warning to use in the pragma is the name that is printed as part of the warning message. A value of default restores the state of the warning to what was specified on the command line with -w, -W, +W, and -FW options.
- #pragma bitfield_packing on|off
This pragma affects the algorithm used when allocating bitfields within structures, and affects all structure definitions that follow. It allows for much greater flexibility when defining structures that must conform to external layout requirements. When bitfield packing is off (the default), the algorithm used is the one common to most other C and C++ compilers. If a bitfield is of type T, then it causes the structure containing it to have an alignment at least as great as the alignment of T. It may not cross a sizeof(T) boundary. (For example, a bitfield of type int may not cross a word boundary, and a bitfield of type char may not cross a byte boundary.) If it is the first bitfield in a series, it is aligned as if it were not a bitfield. When bitfield packing is on, bitfields are packed as tightly as possible. Each bitfield starts immediately following the field before it, even if that means the bitfield will cross a word boundary. Bitfields do not effect the alignment of the structure containing them.
- #pragma double_alignment 4|8
(SPARC targets only.) The value of the pragma, which must be either 4 or 8, specifies the alignment that the compiler assumes when accessing objects of type double or long double that are in memory. The default is 8. This pragma affects the entire source file in which it appears (including code that preceeds the pragma). Use of this pragma should not be necessary if all code in the program is compiled by the Apex compiler. Use of this pragma may be necessary when linking with code compiled by another compiler that only aligns values of type double on four-byte boundaries. If the program tries to access a double value that is only four-byte aligned without a
#pragma double_alignment 4
Compatibility ModeCompatibility mode is specified by use of the -K option on the command line to the Apex C compiler. This mode changes the semantic meaning of some constructs, and relaxes syntatic and semantic checking of others.
Changes Which Affect Program Meaning
- Functions defined as returning type float actually return type double.
- Integral parameter types are widened to int at the point of the call.
- Floating-point parameters are passed as doubles, then converted to float in the function prologue if necessary.
- Comments are not treated as white space in compatibility mode. This means that the preprocessor can be used to concatenate strings to create a valid C name without the use of the special ## concatenation operator introduced by ANSI C.
Illegal Constructs Allowed
The following are accepted in compatibility mode. These are accepted silently unless explicitly noted as giving a warning below.
- A static declaration at file scope is allowed to override a previous external declaration, as long as they're of the same type. Example:
int i; static int i; /* Allowed in compatibility mode */ static char i; /* Error in compatibility and ANSI mode */
- Multiple static declarations are allowed at file scope, as long as they're of the same type. Example:
static int i; static int i; /* Allowed in compatibility mode */ static char i; /* Error in compatibility and ANSI mode */
- A function definition is allowed as the last item of a list of function declarations. Example:
int f(), g(){}; /* Warning only in compatibility mode */
- Untyped declarations of variables default to type int. Example:
j; /* OK in compat mode, "int j;" */ k = 3; /* OK in compat mode, "int k = 3;" */
- Empty declarations are allowed. Example:
int i;; /* Warning in compatibility mode */
- A file containing no tokens (i.e. empty or only containing comments) compiles without error in compatibility mode.
- A function may be called with fewer or more arguments than are in its declaration. Example:
int f(i) int i; { return i; } void g() { f(); /* Warning instead of error */ f(1); /* OK */ f(1, 2, 3); /* Warning instead of error */ }
- In ANSI C, assignment of a function with unspecified type to a function pointer variable is not allowed if the formal parameter list contains a type which is widened by default. Example:
int (*f) (float); int (*g) (double); int (*h) (); void foo() { f = h; /* Allowed in compatibility mode */ g = h; /* Allowed in ANSI and compat mode */ }
Warning Messages Suppressed
In ANSI mode, the Apex C compiler warns against the usage of many constructs which are considered unsafe or obsolete by the ANSI C standards committee. Many of these messages warning of possible program errors are disabled in compatibility mode.
Though the compiler warns against the following constructs in ANSI mode, an object file is still produced.
- No warning is given if the function main returns a type other than int.
- No warning is given if a function with an unspecified return type (meaning the return type defaults to int) does not return a value. Example:
f() { } /* No warning in compatibility mode */
- No warning is given if an undeclared function is called. Example:
void foo() { undeclared_call(); /* No warning in compat mode*/ }
- No warning is given if a bitfield is of a type other than int, signed int, or unsigned int. Example:
struct s { char i: 5; /* No warning in compatibility mode*/ }
- No warnings are given for partially bracketed initializations. Example:
typedef struct { int i, j; } t; static t a[] = { { 0, 0 } }; /* Fully bracketed. No warning in either mode */ static t b[] = { 0, 0 }; /* Partially bracketed. Warning in ANSI, but not in compatibility mode. */
- In ANSI C, preprocessor directives may not be followed by additional text. Example:
#endif any text /* No warning in compat mode */
Implementation-Defined, Unspecified, and Undefined BehaviorsThe ISO/ANSI C standard lists a number of behaviors that are implementation-defined. Implementations are required to document all of these behaviors. The standard also lists a large number of circumstances in which the behavior is unspecified or undefined. We have chosen to document the behavior in some of those circumstances. Because the operating system on which Apex C/C++ is run is always under the control of another company, we cannot fully document all the implementation-defined behaviors, but must is some cases refer the user to the operating system documentation. It is important to remember that none of the behaviors listed below should be relied upon when writing portable applications. Some of them are common to most UNIX systems, others to a particular variety of UNIX, and some are unique to this implementation. Any of them may be changed in a future release of the compiler.
Implementation-Defined Behavior
Translation
- How a diagnostic is identified: Any message from the compiler that contains either of the words "Error" or "Warning".
Environment
- The semantics of the arguments to main: For native systems, the strings pointed to by the second argument are the contents of the argument strings passed to the exec system call that caused the program to be started. For embedded systems, command-line arguments are not supported. The first argument to main is always zero. The second is always a pointer to a null pointer.
- What constitutes an interactive device: For native systems, those devices recognized by the operating system function isatty. For embedded systems, those devices recognized by the operating system as interactive.
Identifiers
- The number of significant initial characters in an identifier without external linkage: Unlimited.
- The number of significant initial characters in an identifier with external linkage: 197. A hashing scheme is used for longer identifiers, so the chance of conflict between identifiers with the same initial 197 characters is slight.
- Whether case distinctions are significant in an identifier with external linkage: Yes.
Characters
- The members of the source and execution character sets: Both the source and execution character sets are standard 7-bit ASCII.
- The shift states used for the encoding of multibyte characters: For native systems, those defined in the current locale by the host system. For embedded systems, multibyte characters are not supported.
- The mapping of members of the source character set to members of the execution character set: The source and execution character sets are identical.
- The value of an integer character constant that contains a character or escape sequence not represented in the basic execution character set or the extended character set for a wide character constant: It has the same value as it does in the source character set.
- The value of an integer character constant that contains more than one character or a wide character constant more than one multibyte character: Wide character constants have the value of the last character in the constant. The value of a regular character constant is the values of the last four characters concatenated together. For example, 'ab' has the value (('a' << 8) | 'b'), and 'abcde' has the value (('b' << 24') | ('c' << 16) | ('d' << 8) | 'e').
- The current locale used to convert multibyte characters into corresponding wide characters (codes) for a wide character constant: For native systems, defined by the environment variable LANG or LC_CTYPE, or "C" by default. For embedded systems, multibyte characters are not supported.
- Whether a "plain" char has the same range of values as signed char or unsigned char: By default, unsigned char for AIX, IRIX, and PowerPC embedded targets, signed char for all other targets. The default may be overridden by the -signed and -unsigned options.
Integers
- The representation and sets of values of the various types of integers: Two's-complement binary representation is used for all integers, with the following sizes:
char: 8 bits
short int: 16 bits
int 32 bits
long int (32-bit systems) 32 bits
long int (64-bit systems) 64 bits
- The result of converting an integer to a shorter signed integer: The high-order bits are discarded and the low-order bits are unchanged.
- The result of converting an unsigned integer to a signed integer of equal length, if the value cannot be represented: The bit pattern is unchanged.
- The result of bitwise operations on signed integers: The resulting bit pattern is the same as if the operation had been performed on unsigned integers with the same bit pattern.
- The sign of the remainder on integer division: The same sign as the first operand.
- The result of a right shift of a negative-valued signed integral type: The shift is arithmetic, so the sign bit is preserved.
Floating Point
- The representation and sets of values of the various types of floating-point numbers: The type float conforms to the 32-bit IEEE floating-point format. The types double and long double are identical and conform to the 64-bit IEEE floating-point format.
- The direction of truncation when an integral number is converted to a floating-point number that cannot exactly represent the original value: Rounding.
- The direction of truncation or rounding when a floating-point number is converted to a narrower floating-point number: Rounding.
Arrays and Pointers
- The type of integer required to hold the maximum size of an array -- that is, the type of the sizeof operator, size_t: The same as the host C compiler, which is usually unsigned int on 32-bit systems and unsigned long on 64-bit systems.
- The result of casting a pointer to an integer or vice versa: When casting a pointer to an integer, the bit pattern is unchanged. If the integer is smaller than the pointer, the high-order bits of the pointer are discarded. When casting an integer to a pointer, the integer is zero-extended if necessary, and the bit pattern is unchanged.
- The type of integer required to hold the difference between two pointers to elements of the same array, ptrdiff_t: The same as the host C compiler, which is usually int on 32-bit systems and long int on 64-bit systems.
Registers
- The extent to which objects can actually be placed in registers by use of the register storage-class specifier: The register storage-class specifier is ignored. The compiler always attempts to put objects in registers as much as possible.
Structures, Unions, Enumerations, and Bit-Fields
- A member of a union object is accessed using a member of a different type: Undefined.
- The padding and alignment of members of structures: The alignment of the built-in types is the same as their size (except for AIX, where the alignment of types double and long double is four instead of eight), and padding is added to structures so that each member is properly aligned.
- Whether a "plain" int bit-field is treated as a signed int bit-field or as an unsigned int bit-field: unsigned int bit-field.
- The order of allocation of bit-fields within a unit: High-order bits to low-order bits.
- Whether a bit-field can straddle a storage-unit boundary: A bit-field can straddle a word (32-bit or 64-bit) boundary only if #pragma bitfield_packing is in effect.
- The integer type chosen to represent the values of an enumeration type: int.
Qualifiers
- What constitutes an access to an object that has volatile-qualified type: A single copy from memory to a CPU register or vice versa.
Declarators
- The maximum number of declarators that may modify an arithmetic, structure, or union type: Unlimited.
Statements
- The maximum number of case values in a switch statement: About 65,000. The limit may actually be less if there is additional code in the same source file.
Preprocessing Directives
- Whether the value of a single-character constant in a constant expression that controls conditional inclusion matches the value of the same character constant in the execution character set: Yes.
- Whether such a character constant may have a negative value: Yes.
- The method for locating includable source files: The compiler looks for the specified file in a number of directories. The directories that are searched depends on where the compiler was installed and what mode it is in. To see which directories are being searched, use the -v option to the compiler and look at the -I options passed to the front end. The directories that are searched can be modified with the -I and -noinc options to the compiler.
- The support of quoted names for includable source files: If the file name begins with a slash '/', then the compiler will look for a file with that exact name. Otherwise, the compiler looks for the file in the same directory as the file currently being translated before looking in the other directories described above.
- The mapping of source file character sequences: The string of source file characters is treated as the name of the file to be included.
- The behavior on each recognized #pragma directive: See Supported Pragmas.
- The definitions for __DATE__ and __TIME__ when respectively, the date and time of translation are not available: The date and time of Dec 31 23:59:59 GMT 1969, converted to the local time zone
Library Functions
The following implementation-defined behaviors are dependent on the target operating system. The behaviors listed apply only to embedded targets. For native systems, the host system documentation must be consulted.
- The null pointer constant to which the macro NULL expands: ((void *)0).
- The diagnostic printed by and the termination behavior of the assert function: Prints to stderr "***Assertion failed in file %s line %d:\n\t%s\n", where %s, %d, and %s are replaced by the values of the macros __FILE__ and __LINE__ and the argument to the assert macro, respectively. Then the function abort is called.
- The sets of characters tested for by the isalnum, isalpha, iscntrl, islower, isprint, and isupper functions:
isalnum: A-Z, a-z, 0-9
isalpha: A-Z, a-z
iscntrl: \0-\037, \0177
islower: a-z
isprint: space,!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~, A-Z, a-z, 0-9
isupper: A-Z
- The values returned by the mathematics function on domain errors: Positive or negative infinity.
- Whether the mathematics functions set the integer expression errno to the value of the macro ERANGE on underflow range errors: No.
- Whether a domain error occurs or zero is returned when the fmod function has a second argument of zero: A domain error occurs.
- The set of signals recognized by the signal function, their default handling, and their semantics: Signals are never raised asynchronously; they can only be raised by calling the functions raise or abort. The default behaviors for all signals is to exit the process without flushing any I/O buffers or closing any open files. The signals that are recognized are: SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, and SIGTERM.
- If the equivalent of signal(sig, SIG_DFL); is not executed prior to the call of a signal handler, the blocking of the signal that is performed: The equivalent of signal(sig, SIG_DFL); is always executed prior to the call of a signal handler.
- Whether the default handling is reset if the SIGILL signal is received by a handler specified to the signal function: Yes.
- Whether the last line of a text stream requires a terminating new-line character: No.
- Whether space characters that are written out to a text stream immediately before a new-line character appear when read in: Yes.
- The number of null characters that may be appended to data written to a binary stream: Zero.
- Whether the file position indicator of an append mode stream is initially positioned at the beginning or end of the file: The end of the file.
- Whether a write on a text stream causes the associated file to be truncated beyond that point: No.
- The characteristics of file buffering: File buffering is implemented as intended in section 4.9.3 of the ANSI C standard.
- Whether a zero-length file actually exists: Yes.
- The rules for composing valid file names: A file name is a string of up to 1023 characters. The characters may have any value other than'\0'. The string is divided into components which are separated by slashes ('/'). Each component must be no longer than 255 characters. All the components other than the last one specify the directory in which the file is located. If a file is being created, that directory must already exist.
- Whether the same file can be open multiple times: Yes.
- The effect of the remove function on an open file: The file can no longer be accessed by that name, but it continues to exist until it is closed.
- The effect if a file with the new name exists prior to a call to the rename function: The rename function is not supported, so the file is unaffected.
- The output for %p conversion in the fprintf function: fprintf(fp, "%p", p) is equivalent to fprintf(fp, "%lx", (unsigned long)p).
- The input for %p conversion in the fscanf function: The same as for %lx.
- The interpretation of a - character that is neither the first nor the last character in the scanlist for %[ conversion in the fscanf function: Given the sequence of characters "p-q" in the scanlist. If 'p' < 'q', then fscanf behaves as if all the characters whose values are between 'p' and 'q' were in the scanlist. Otherwise, the '-' is interpreted as if it were a normal character.
- The value to which the macro errno is set by the fgetpos or ftell function on failure: It depends on the reason for the failure.
- The behavior of the calloc, malloc, or realloc function if the size requested is zero: A NULL pointer is returned.
- The behavior of the abort function with regard to open and temporary files: The files are closed, but any data in the program's buffers is lost.
- The status returned by the exit function if the value of the argument is other than zero, EXIT_SUCCESS, or EXIT_FAILURE: The value of the argument to exit is returned.
- The set of environment names and the method for altering the environment list used by the getenv function: The getenv function is not supported and always returns a null pointer.
- The contents and mode of execution of the string by the system function: The system function is not supported and always returns zero.
- The contents of the error message strings returned by the strerror function:
- The local time zone and Daylight Savings Time: Time zones and Daylight Savings Time are not supported.
- The era for the clock function: The first call to clock always returns 0. Subsequent calls return the amount of processor time since the first call to clock.
Unspecified Behavior
Specified in This Implementation
The following behaviors, listed as unspecified by the ISO/ANSI C standard, are defined in this implementation.
- The representation of floating types: The 32-bit and 64-bit versions of IEEE floating-point are used.
- The alignment of the addressable storage unit allocated to hold a bit-field: 4 bytes, unless #pragma bitfield_packing is used.
- Whether setjmp is a macro or an external identifier: External identifier.
- Whether va_end is a macro or an external identifier: Macro.
- The encoding of the calendar time returned by the time function: Number of seconds since Jan 1 00:00:00 GMT 1970.
Other behaviors listed as unspecified by the ISO/ANSI C standard are left unspecified in this implementation.
Undefined Behavior
Compile-Time Errors
The following behaviors, listed as undefined by the ISO/ANSI C standard, result in compile-time errors in this implementation.
- A nonempty source file ends in a partial preprocessing token or comment.
- A character not in the required character set is encountered in a source file, except in a preprocessing token that is never converted to a token, a character constant, a string literal, a header name, or a comment.
- A comment, string literal, character constant, or header name contains an invalid multibyte character or does not begin and end in the initial shift state.
- An unmatched ' or " character is encountered on a logical source line during tokenization.
- The same identifier is used more than once as a label in the same function.
- An identifier is used that is not visible in the current scope.
- The same identifier has both internal and external linkage in the same translation unit.
- A character string literal token is adjacent to a wide string literal token.
- An lvalue with an incomplete type is used in a context that requires the value of the designated object.
- The value of a void expression is used or an implicit conversion (except to void) is applied to a void expression.
- An argument to a function is a void expression.
- A pointer is converted to other than an integral or pointer type.
- An identifier for an object is declared with no linkage and the type of the object is incomplete after its declarator, or after its init-declarator if it has an initializer.
- An object with aggregate or union type with static storage duration has a non-brace-enclosed initializer, or an object with aggregate or union type with automatic storage duration has either a single expression initializer with a type other than that of the object or a non-brace-enclosed initializer.
- An identifier for an object with internal linkage and an incomplete type is declared with a tentative definition.
- The #include preprocessing directive that results after expansion does not match one of the two header name forms.
- The #line preprocessing directive that results after expansion does not match one of the two well-defined forms.
- One of the following identifiers is the subject of a #define or #undef preprocessing directive: defined, __LINE__, __FILE__, __DATE__, __TIME__, or __STDC__.
- The parameter member-designator of an offsetof macro is an invalid right operand of the operator for the type parameter or designates bit-field member of a structure.
- The macro definition of assert is suppressed to obtain access to an actual function.
- A macro definition of va_start, va_arg, or va_end or a combination thereof is suppressed to obtain access to an actual function.
Other Behavior
The following behaviors, listed as undefined by the ISO/ANSI C standard, are documented (to some extent) in this implementation.
- A nonempty source file does not end in a new-line character, or ends in a new-line character immediately preceded by a backslash: The compiler behaves as if an extra new-line character was appended to the file.
- Identifiers that are intended to denote the same entity differ in a character beyond the minimal significant characters: The two identifiers will most likely be interpreted as different.
- Two declarations of the same object or function specify types that are not compatible: If the declarations are in the same translation unit, it will be a compile-time error. Otherwise, the behavior is undefined.
- An unspecified escape sequence is encountered in a character constant or string literal: The compiler behaves as if the \ preceding the unspecified escape sequence was not present. For example, '\z' is the same as 'z'.
- An attempt is made to modify a string literal of either form: Either the attempt will succeed, or a SIGSEGV signal will be sent to the process.
- The characters ', \, ", or /* are encountered between the < and > delimiters or the characters ', \, or /* are encountered between the " delimiters in the two forms of a header name preprocessing token: The characters are interpreted as part of the file name.
- An arithmetic operation produces a result that cannot be represented in the space provided (such as overflow or underflow): For integer operations, modulo arithmetic is used for both signed and unsigned types. For floating-point operations, the operation will result in the value NaN, +Inf, -Inf, or zero, depending on the operation.
- For a function call without a function prototype, the number of arguments does not agree with the number of parameters: If the number of arguments is greater than the number of parameters, then the values of the extra arguments are discarded and the called function behaves as if it had been called with the correct number of arguments. If there are fewer arguments than parameters, the behavior is undefined.
- A function that accepts a variable number of arguments is called without a function prototype that ends with an ellipsis: If adding the proper prototype would not cause any compile-time errors, then the program will behave the same with or without the prototype. Otherwise, the behavior is undefined.
- A pointer that does not behave like a pointer to an element of an array object is added to or subtracted from: Arithmetic on the pointer will behave as expected, but undefined behavior will result if the value pointed to by the result is accessed.
- A structure or union is defined as containing only unnamed members: The definition is accepted without comment.
- A bit-field is declared with a type other than int, signed int, or unsigned int: The compiler issues a warning and then treats the declaration as if the base type were int (with any specified signed or unsigned modifiers).
- An attempt is made to refer to an object with volatile-qualified type by means of an lvalue with non-volatile-qualified type: The reference will succeed as if the object did not have a volatile-qualified type.
- The token defined is generated during the expansion of a #if or #elif preprocessing directive: The newly-generated defined token is recognized by the compiler and treated like a regular defined token.
- A macro argument consists of no preprocessing tokens: The macro is expanded normally, with the argument in question being replaced by nothing.
- There are sequences of preprocessing tokens within the list of macro arguments that would otherwise act as preprocessing directive lines: These are not recognized as preprocessing directives, either before or after substitution.
- The result of the preprocessing concatenation operator ## is not a valid preprocessing token: The result is divided into several different preprocessing tokens.
- A library function that accepts a variable number of arguments is not declared: If adding the proper prototype would not cause any compile-time errors, then the program will behave the same with or without the prototype. Otherwise, the behavior is undefined.
- The macro definition of setjmp is suppressed to obtain access to an actual function: setjmp is a function and not a macro, so the program will behave as if the macro definition had not been suppressed.
- The longjmp function is invoked from a nested signal routine: There is nothing special about jumping out of a signal handler, so the program will behave as expected.
- A signal occurs other than as the result of calling the abort or raise function, and the signal handler calls any function in the standard library other than the signal function itself or refers to any object with static storage duration other than by assigning a value to a static storage duration variable of type volatile sig_atomit_t: For native systems, most library functions should work as expected, the biggest exception being I/O functions that deal with buffered streams. Referring to objects should work unless they are in the process of being modified. For embedded systems, since signals are never delivered to the process asynchronously, all library functions should behave normally.
- The value of errno is referred to after a signal occurs other than as the result of calling the abort or raise function and the corresponding signal handler calls the signal function such that it returns the value SIG_ERR: For native systems, errno will have the value given it by the signal handler. For embedded systems, a signal cannot occur other than by calling abort or raise, so this situation cannot occur.
- The macro va_arg is invoked with the parameter ap that was passed to a function that invoked the macro va_arg with the same parameter: The invocation of va_arg in question will behave as if the called function had not invoked va_arg.
- The parameter parmN of a va_start macro is declared with the register storage class, or with a function or array type, or with a type that is not compatible with the type that results after application of the default argument promotions: The parameter parmN of a va_start macro is ignored, so it doesn't matter how it was declared.
- The va_end macro is invoked without a corresponding invocation if the va_start macro: va_end does not depend on a previous invocation of va_start and may be invoked at any time.
- A return occurs from a function with a variable argument list initialized by the va_start macro before the va_end macro is invoked: The program will behave as if va_end had been invoked immediately before the return.
Left Undefined
Other behaviors listed as undefined in the ISO/ANSI C standard are left undefined in this implementation.
Rational Software Corporation http://www.rational.com support@rational.com techpubs@rational.com Copyright © 1993-2002, Rational Software Corporation. All rights reserved. |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |