Annex C (informative) Compatibility [diff] (original) (raw)

C.7 C++ and C [diff.iso]

C.7.4 [expr]: expressions [diff.expr]

Affected subclause: [conv.ptr]

Change: Converting void* to a pointer-to-object type requires casting.

[Example 1: char a[10];void* b=a;void foo() { char* c=b;}

C accepts this usage of pointer to void being assigned to a pointer to object type.

C++ does not.

— _end example_]

Rationale: C++ tries harder than C to enforce compile-time type safety.

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Can be automated.

Violations will be diagnosed by the C++ translator.

The fix is to add a cast.

[Example 2: char* c = (char*) b; — _end example_]

How widely used: This is fairly widely used but it is good programming practice to add the cast when assigning pointer-to-void to pointer-to-object.

Some C translators will give a warning if the cast is not used.

Affected subclause: [expr.arith.conv]

Change: Operations mixing a value of an enumeration type and a value of a different enumeration type or of a floating-point type are not valid.

[Example 3: enum E1 { e };enum E2 { f };int b = e <= 3.7; int k = f - e; int x = 1 ? e : f; — _end example_]

Rationale: Reinforcing type safety in C++.

Effect on original feature: Well-formed C code will not compile with this International Standard.

Difficulty of converting: Violations will be diagnosed by the C++ translator.

The original behavior can be restored with a cast or integral promotion.

[Example 4: enum E1 { e };enum E2 { f };int b = (int)e <= 3.7;int k = +f - e; — _end example_]

How widely used: Uncommon.

Affected subclauses: [expr.post.incr] and [expr.pre.incr]

Change: Decrement operator is not allowed with bool operand.

Rationale: Feature with surprising semantics.

Effect on original feature: A valid C expression utilizing the decrement operator on a bool lvalue (for instance, via the C typedef in ) is ill-formed in C++.

Affected subclauses: [expr.sizeof] and [expr.cast]

Change: In C++, types can only be defined in declarations, not in expressions.

In C, a sizeof expression or cast expression may define a new type.

[Example 5:

p = (void*)(struct x {int i;} *)0;defines a new type, struct x.

— _end example_]

Rationale: This prohibition helps to clarify the location of definitions in the source code.

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Syntactic transformation.

How widely used: Seldom.

Affected subclauses: [expr.rel] and [expr.eq]

Change: C allows directly comparing two objects of array type; C++ does not.

Rationale: The behavior is confusing because it compares not the contents of the two arrays, but their addresses.

Effect on original feature: Deletion of semantically well-defined feature that had unspecified behavior in common use cases.

Difficulty of converting: Violations will be diagnosed by the C++ translator.

The original behavior can be replicated by explicitly casting either array to a pointer, such as by using a unary +.

[Example 6: int arr1[5];int arr2[5];int same = arr1 == arr2; int idem = arr1 == +arr2; — _end example_]

How widely used: Rare.

Affected subclauses: [expr.cond], [expr.assign], and [expr.comma]

Change: The result of a conditional expression, an assignment expression, or a comma expression may be an lvalue.

Rationale: C++ is an object-oriented language, placing relatively more emphasis on lvalues.

For example, function calls may yield lvalues.

Effect on original feature: Change to semantics of well-defined feature.

Some C expressions that implicitly rely on lvalue-to-rvalue conversions will yield different results.

[Example 7:

char arr[100];sizeof(0, arr) yields100in C++ andsizeof(char*)in C.

— _end example_]

Difficulty of converting: Programs must add explicit casts to the appropriate rvalue.

How widely used: Rare.