C User's Guide HomeContentsPreviousNextIndex


Appendix D

The Differences Between K&R Sun C and Sun ANSI/ISO C

This appendix describes the differences between the previous K&R Sun C and Sun ANSI/ISO C. This appendix is organized into the following sections:

For more information see Standards Conformance.

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

TABLE D-1   K&R Sun C Incompatibilities with Sun ANSI/ISO C  
Topic Sun C (K&R) 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-character 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/union members 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__


The Difference Between Sun C and ANSI/ISO C As Set By -Xs

This section describes the differences in compiler behavior when using the
-Xs option. The -Xs option tries to emulate Sun C 1.0, and Sun C 1.1 (K&R style), but in some cases it cannot emulate the previous behavior.

TABLE D-2   -Xs Behavior
Data Type Sun C (K&R) Sun ANSI/ISO C
Aggregate initialization:
struct
{
int a[3];
int b;
}
w[] = {{1},2};
sizeof (w) = 16
w[0].a = 1, 0, 0
w[0].b =2
sizeof(w) = 32
w[0].a = 1, 0, 0
w[0].b = 0
w[1].a = 2, 0, 0
w[1].b = 0
Incomplete struct, union, enum declaration struct fq {
int i;
struct unknown;
};
Does not allow incomplete struct, union, and enum declaration.
Switch expression integral type Allows non-integral type. Does not allow non-integral type.
Order of precedence Allows:
if (rcount > count += index)
Does not allow:
if (rcount > count += index)
unsigned, short, and
long typedef declarations
Allows:
typedef short small
unsigned small;
Does not allow (all modes).
struct or union tag mismatch in nested struct or union
declarations
Allows tag mismatch:
struct x
{
int i;
}
s1;
/* K&R treats as a struct */
{
union x s2;
}
Does not allow tag mismatch in nested struct or union declaration.
Incomplete struct or union type Ignores an incomplete type declaration. struct x
{
int i;
}
s1;

main()
{
struct x;
struct y
{
struct x f1

/* in K&R, f1 refers */
/* to outer struct */
} s2;
struct x {
int i;
};
}
Casts as lvalues Allows:
(char *) ip = &foo;
Does not allow casts as lvalues (all modes).


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 D-3   ANSI/ISO C Standard Keywords
auto break case char
const continue default do
double else enum extern
float for goto if
int long register return
short signed sizeof static
struct switch typedef union
unsigned void volatile while


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

Keywords in Sun C are listed below.

TABLE D-4   Sun C (K&R) Keywords
asm auto break case
char continue default do
double else enum extern
float for fortran goto
if int long register
return short sizeof static
struct switch typedef union
unsigned void while



Sun Microsystems, Inc.
Copyright information. All rights reserved.
Feedback
Library   |   Contents   |   Previous   |   Next   |   Index