Sun WorkShop Compiler C 5.0 User's Guide

Appendix G K&R Sun C / Sun ANSI/ISO C Differences

This appendix describes the differences between the previous K&R Sun C and Sun ANSI/ISO C.

"K&R Sun C Incompatibilities with Sun ANSI/ISO C " describes previous Sun C features incompatible with Sun ANSI/ISO C. These differences should be addressed when porting source code written for the Sun C compiler to Sun ANSI/ISO C.

"Keywords " lists reserved words used by the ANSI/ISO C standard, Sun ANSI/ISO C, Sun C, and those defined by the Sun ANSI/ISO and Sun C preprocessors.

K&R Sun C Incompatibilities with Sun ANSI/ISO C

Table G-1 K&R Sun C Incompatibilities with Sun ANSI/ISO C

Topic 

Sun C 

Sun ANSI/ISO C 

envp argument to main()

Allows envp as third argument to main().

Allows this third argument; however, this usage is not strictly conforming to the ANSI/ISO C standard. 

Keywords  

Treats the identifiers const, volatile, and signed as ordinary identifiers.

const, volatile, and signed are keywords.

extern and static functions declarations inside a block

Promotes these function declarations to file scope. 

The ANSI/ISO standard does not guarantee that block scope function declarations are promoted to file scope. 

Identifiers  

Allows dollar signs ($) in identifiers.

$ not allowed.

long float types

Accepts long float declarations and treats these as double(s).

Does not accept these declarations.  

Multi-byte character constants  

int mc = 'abcd';

yields: 

abcd

int mc = 'abcd';

yields: 

dcba

Integer constants  

Accepts 8 or 9 in octal escape sequences. 

Does not accept 8 or 9 in octal escape sequences.  

Assignment operators  

Treats the following operator pairs as two tokens, and as a consequence, permits white space between them:  

 

*=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=

Treats them as single tokens, and therefore disallows white space in between.  

Unsigned preserving semantics for expressions  

Supports unsigned preserving, that is, unsigned char/shorts are converted into unsigned int(s).

Supports value-preserving, that is, unsigned char/short(s) are converted into int(s).

Single/double precision calculations  

Promotes the operands of floating point expressions to double.

 

Functions which are declared to return floats always promote their return values to doubles.

Allows operations on floats to be performed in single precision calculations.

 

Allows float return types for these functions.

 

 

Name spaces of struct/unionmembers

Allows struct, union, and arithmetic types using member selection operators ('.', '->') to work on members of other struct(s) or unions.

Requires that every unique struct/union have its own unique name space.

A cast as an lvalue

Supports casts as lvalue(s). For example:

 

(char *)ip = &char;

Does not support this feature.  

Implied int declarations

Supports declarations without an explicit type specifier. A declaration such as num; is treated as implied int. For example:

 

num; /* num implied as an int */

int num2; /* num2 explicitly declared an int */

The num; declaration (without the explicit type specifier int) is not supported, and generates a syntax error.

Empty declarations  

Allows empty declarations, such as: 

int;

Except for tags, disallows empty declarations.  

Type specifiers on type definitions  

Allows type specifiers such as unsigned, short, long on typedefs declarations. For example:

 

typedef short small;

unsigned small x;

Does not allow type specifiers to modify typedef declarations.

Types allowed on bit fields  

Allows bit fields of all integral types, including unnamed bit fields. 

 

The ABI requires support of unnamed bit fields and the other integral types. 

Supports bitfields only of the type int, unsigned int and signed int. Other types are undefined.

Treatment of tags in incomplete declarations 

Ignores the incomplete type declaration. In the following example, f1 refers to the outer struct:

 

struct x { . . . } s1; { struct x; struct y {struct x f1; } s2; struct x { . . . }; }

In an ANSI/ISO-conforming implementation, an incomplete struct or union type specifier hides an enclosing declaration with the same tag.

Mismatch on struct/union/enum declarations

Allows a mismatch on the struct/enum/union type of a tag in nested struct/union declarations. In the following example, the second declaration is treated as a struct:

 

struct x {. . . }s1; { union x s2; . . . }

Treats the inner declaration as a new declaration, hiding the outer tag.  

 

Labels in expressions  

Treats labels as (void *) lvalues.

Does not allow labels in expressions.  

switch condition type

Allows float(s) and double(s) by converting them to int(s).

Evaluates only integral types (int, char, and enumerated) for the switch condition type.

Syntax of conditional inclusion directives  

The preprocessor ignores trailing tokens after an #else or #endif directive.

Disallows such constructs.  

Token-pasting and the ## preprocessor operator

Does not recognize the ## operator. Token-pasting is accomplished by placing a comment between the two tokens being pasted:

 

#define PASTE(A,B) A/*any comment*/B

Defines ## as the preprocessor operator that performs token-pasting, as shown in this example:

 

 

#define PASTE(A,B) A##B

 

Furthermore, the Sun ANSI/ISO C preprocessor doesn't recognize the Sun C method. Instead, it treats the comment between the two tokens as white space.  

Preprocessor rescanning  

The preprocessor recursively substitutes: 

 

#define F(X) X(arg) F(F)

 

yields 

 

arg(arg)

A macro is not replaced if it is found in the replacement list during the rescan:  

 

#define F(X)X(arg) F(F)

 

yields: 

 

F(arg)

typedef names in formal parameter lists

You can use typedef names as formal parameter names in a function declaration. "Hides" the typedef declaration.

Disallows the use of an identifier declared as a typedef name as a formal parameter.

Implementation-specific initializations of aggregates  

Uses a bottom-up algorithm when parsing and processing partially elided initializers within braces: 

 

struct{ int a[3]; int b; }\ w[]={{1},2};

 

yields 

 

sizeof(w)=16 w[0].a=1,0,0 w[0].b=2

Uses a top-down parsing algorithm. For example: 

 

struct{int a[3];int b;}\ w[]={{1},2};

 

yields 

 

sizeof(w)=32 w[0].a=1,0,0 w[0].b=0 w[1].a=2,0,0 w[1].b=0

Comments spanning include files

Allows comments which start in an #include file to be terminated by the file that includes the first file.

Comments are replaced by a white-space character in the translation phase of the compilation, which occurs before the #include directive is processed.

Formal parameter substitution within a character constant  

Substitutes characters within a character constant when it matches the replacement list macro: 

 

#define charize(c)'c' charize(Z)

 

yields: 

 

'Z'

The character is not replaced: 

 

#define charize(c) 'c' charize(Z)

 

yields: 

 

'c'

Formal parameter substitution within a string constant  

The preprocessor substitutes a formal parameter when enclosed within a string constant: 

 

#define stringize(str) 'str' stringize(foo)

 

yields: 

 

"foo"

The # preprocessor operator should be used:

 

#define stringize(str) 'str' stringize(foo)

 

yields: 

 

"str"

 

Preprocessor built into the compiler "front-end" 

Compiler calls cpp(1).

 

Components used in the compiling are: 

 

cpp ccom iropt cg inline as ld

 

Note: iropt and cg are invoked only with the following options:

 

-O -xO2 -xO3 -xO4 -xa -fast

 

inline is invoked only if an inline template file (file.il) is provided.

Preprocessor (cpp) is built directly into acomp, so cpp is not directly involved, except in -Xs mode.

 

Components used in the compiling are: 

 

cpp (-Xs mode only) acomp iropt cg ld

 

Note: iropt and cg are invoked only with the following options:

 

-O -xO2 -xO3 -xO4 -xa -fast

 

 

Line concatenation with backslash  

Does not recognize the backslash character in this context.  

Requires that a newline character immediately preceded by a backslash character be spliced together. 

Trigraphs in string literals  

Does not support this ANSI/ISO C feature.  

 

asm keyword

asm is a keyword.

asm is treated as an ordinary identifier.

Linkage of identifiers 

Does not treat uninitialized static declarations as tentative declarations. As a consequence, the second declaration will generate a 'redeclaration' error, as in:

 

static int i = 1;

 

static int i;

 

Treats uninitialized static declarations as tentative declarations.

Name spaces  

Distinguishes only three : struct/union/enum tags, members of struct/union/enum, and everything else.

Recognizes four distinct name spaces: label names, tags (the names that follow the keywords struct, union or enum), members of struct/union/enum, and ordinary identifiers.

long double type

Not supported.  

Allows long double type declaration.

Floating point constants  

The floating point suffixes, f, l, F, and L, are not supported.

 

Unsuffixed integer constants can have different types  

The integer constant suffixes u and U are not supported.

 

Wide character constants  

Does not accept the ANSI/ISO C syntax for wide character constants, as in: 

 

wchar_t wc = L'x';

Supports this syntax. 

 

 

'\a' and '\x'

Treats them as the characters 'a' and 'x'.

Treats '\a' and '\x' as special escape sequences.

Concatenation of string literals 

Does not support the ANSI/ISO C concatenation of adjacent string literals.  

 

Wide character string literal syntax  

Does not support the ANSI/ISO C wide character, string literal syntax shown in this example:  

 

wchar_t *ws = L"hello";

Supports this syntax. 

Pointers: void * versus char *

Supports the ANSI/ISO C void * feature.

 

Unary plus operator  

Does not support this ANSI/ISO C feature.  

 

Function prototypes-- ellipses  

Not supported.  

ANSI/ISO C defines the use of ellipses "..." to denote a variable argument parameter list.  

Type definitions  

Disallows typedefs to be redeclared in an inner block by another declaration with the same type name.

Allows typedefs to be redeclared in an inner block by another declaration with the same type name.

Initialization of extern variables

Does not support the initialization of variables explicitly declared as extern.

Treats the initialization of variables explicitly declared as extern, as definitions.

Initialization of aggregates  

Does not support the ANSI/ISO C initialization of unions or automatic structures.  

 

Prototypes  

Does not support this ANSI/ISO C feature.  

 

Syntax of preprocessing directive  

Recognizes only those directives with a # in the first column.

ANSI/ISO C allows leading white-space characters before a # directive.

The # preprocessor operator

Does not support the ANSI/ISO C # preprocessor operator. 

 

#error directive

Does not support this ANSI/ISO C feature.  

 

Preprocessor directives  

Supports two pragmas, unknown_control_flow and makes_regs_inconsistent along with the #ident directive. The preprocessor issues warnings when it finds unrecognized pragmas.

Does not specify its behavior for unrecognized pragmas.  

 

 

Predefined macro names  

These ANSI/ISO C-defined macro names are not defined:  

 

__STDC__ __DATE__

__TIME__ __LINE__

 

 

Keywords

The following tables list the keywords for the ANSI/ISO C Standard, the Sun ANSI/ISO C compiler, and the Sun C compiler.

The first table lists the keywords defined by the ANSI/ISO C standard.

Table G-2 ANSI/ISO C Standard Keywords
autobreakcasechar
constcontinuedefaultdo
doubleelseenumextern
floatforgotoif
intlongregisterreturn
shortsignedsizeofstatic
structswitchtypedefunion
unsignedvoidvolatilewhile

Sun ANSI/ISO defines one additional keyword, asm. However, asm is not supported in -Xc mode.

Keywords in Sun C are listed below.

Table G-3 Sun C (K&R) Keywords
asmautobreakcase
charcontinuedefaultdo
doubleelseenumextern
floatforfortrangoto
ifintlongregister
returnshortsizeofstatic
structswitchtypedefunion
unsignedvoidwhile