Go to main content
Oracle® Developer Studio 12.5: C User's Guide

Exit Print View

Updated: June 2017

Oracle Developer Studio C: Differences Between K&R C and ISO C

This appendix describes the differences between the previous K&R Oracle Developer Studio C and Oracle Developer Studio ISO C.

For more information see Standards Conformance.

I.1 Incompatibilities

Table 121  K&R C Incompatibilities With ISO C
Oracle Developer Studio C (K&R)
Oracle Developer Studio 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.
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.
Allows dollar signs ($) in identifiers.
$ not allowed.
long float types
Accepts long float declarations and treats these as double.
Does not accept these declarations.
Multi-character character-constants
int mc = ’abcd’;
int mc = ’abcd’;
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.
Supports value-preserving, that is, unsigned char/short(s) are converted into int.
Single/double precision calculations
Promotes the operands of floating-point expressions to double.
Functions that 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 structs or unions.
Requires that every unique struct/union have its own unique name space.
A cast as an lvalue
Supports casts of integral and pointer types as lvalues. 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, for example:
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 floats and doubles by converting them to ints.
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, for example:
#define PASTE(A,B) A##B
Furthermore, the preprocessor does not recognize the method. Instead, it treats the comment between the two tokens as white space.
Preprocessor rescanning
The preprocessor recursively substitutes:
#define F(X) X(arg)
A macro is not replaced if it is found in the replacement list during the rescan:
#define F(X)X(arg)F(F)
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};
Uses a top-down parsing algorithm. For example:
struct{int a[3];int b;}\
Comments spanning include files
Allows comments that 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’
The character is not replaced:
#define charize(c) ’c’charize(Z)
Formal parameter substitution within a string constant
The preprocessor substitutes a formal parameter when enclosed within a string constant:
#define stringize(str) ’str’
The # preprocessor operator should be used:
#define stringize(str) ’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.
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: