Sun Studio 12: C User's Guide

H.1 K&R Sun C Incompatibilities With Sun ISO C

Table H–1 K&R Sun C Incompatibilities With Sun ISO C

Topic 

Sun C (K&R)  

Sun 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 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 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 bit-fields 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 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 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)=32w[0].a=1,0,0w[0].=0w[1].a=2,0,0w[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 invokes cpp(1) followed by all the other components of the compilation system depending on the options specified.

The ISO C translation phases 1-4, which cover the processing of preprocessor directives, is built directly into acomp, so cpp is not directly invoked during compilation, except in -Xs mode.

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 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 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 ISO C concatenation of adjacent string literals. 

 

Wide character string literal syntax 

Does not support the 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 ISO C void * feature.

 

Unary plus operator 

Does not support this ISO C feature. 

 

Function prototypes— ellipses 

Not supported. 

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 ISO C initialization of unions or automatic structures. 

 

Prototypes 

Does not support this ISO C feature. 

 

Syntax of preprocessing directive 

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

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

The # preprocessor operator

Does not support the ISO C # preprocessor operator. 

 

#error directive

Does not support this 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 ISO C-defined macro names are not defined: 

__STDC__

__DATE__

__TIME__

__LINE__