Annex C (informative) Compatibility [diff]

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; // valid in C; ill-formed in C++ int k = f - e; // valid in C; ill-formed in C++ int x = 1 ? e : f; // valid in C; ill-formed in C++ — 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 <stdbool.h>) 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.cond], [expr.ass], 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 6: 
char arr[100]; sizeof(0, arr) yields 100 in C++ and sizeof(char*) in C.
— end example]

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

How widely used: Rare.