245 lines
7.2 KiB
Markdown
245 lines
7.2 KiB
Markdown
[diff.class]
|
||
|
||
# Annex C (informative) Compatibility [[diff]](./#diff)
|
||
|
||
## C.7 C++ and C [[diff.iso]](diff.iso#diff.class)
|
||
|
||
### C.7.7 [[class]](class "11 Classes"): classes [diff.class]
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L3483)
|
||
|
||
**Affected subclause:** [[class.name]](class.name) [see also [[dcl.typedef]](dcl.typedef "9.2.4 The typedef specifier")]
|
||
|
||
**Change:** In C++, a class declaration introduces the class name into the scope where it is
|
||
declared and hides any object, function or other declaration of that name in an enclosing
|
||
scope[.](#1.sentence-2)
|
||
|
||
In C, an inner scope declaration of a struct tag name never hides the name of an
|
||
object or function in an outer scope[.](#1.sentence-3)
|
||
|
||
[*Example [1](#example-1)*: int x[99];void f() {struct x { int a; }; sizeof(x); /* size of the array in C *//* size of the struct in *C++* */} â *end example*]
|
||
|
||
|
||
|
||
|
||
**Rationale:** This is one of the few incompatibilities between C and C++ that
|
||
can be attributed to the new C++ name space definition where a
|
||
name can be declared as a type and as a non-type in a single scope
|
||
causing the non-type name to hide the type name and requiring that
|
||
the keywords class, struct, union or enum be used to refer to the type name[.](#1.sentence-4)
|
||
|
||
This new name space definition provides important notational
|
||
conveniences to C++ programmers and helps making the use of the
|
||
user-defined types as similar as possible to the use of fundamental
|
||
types[.](#1.sentence-5)
|
||
|
||
The advantages of the new name space definition were judged to
|
||
outweigh by far the incompatibility with C described above[.](#1.sentence-6)
|
||
|
||
|
||
|
||
|
||
**Effect on original feature:** Change to semantics of well-defined feature[.](#1.sentence-7)
|
||
|
||
|
||
|
||
|
||
**Difficulty of converting:** Semantic transformation[.](#1.sentence-8)
|
||
|
||
If the hidden name that needs to be accessed is at global scope,
|
||
the :: C++ operator can be used[.](#1.sentence-9)
|
||
|
||
If the hidden name is at block scope, either the type or the struct
|
||
tag has to be renamed[.](#1.sentence-10)
|
||
|
||
|
||
|
||
|
||
**How widely used:** Seldom[.](#1.sentence-11)
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L3523)
|
||
|
||
**Affected subclause:** [[class.copy.ctor]](class.copy.ctor)
|
||
|
||
|
||
**Change:** Copying volatile objects[.](#2.sentence-1)
|
||
|
||
The implicitly-declared copy constructor and
|
||
implicitly-declared copy assignment operator
|
||
cannot make a copy of a volatile lvalue[.](#2.sentence-2)
|
||
|
||
[*Example [2](#example-2)*:
|
||
|
||
The following is valid in C:struct X { int i; };volatile struct X x1 = {0};struct X x2 = x1; // invalid C++struct X x3;
|
||
x3 = x1; // also invalid C++
|
||
|
||
â *end example*]
|
||
|
||
|
||
|
||
|
||
**Rationale:** Several alternatives were debated at length[.](#2.sentence-4)
|
||
|
||
Changing the parameter tovolatileconstX& would greatly complicate the generation of
|
||
efficient code for class objects[.](#2.sentence-5)
|
||
|
||
Discussion of
|
||
providing two alternative signatures for these
|
||
implicitly-defined operations raised
|
||
unanswered concerns about creating
|
||
ambiguities and complicating
|
||
the rules that specify the formation of
|
||
these operators according to the bases and
|
||
members[.](#2.sentence-6)
|
||
|
||
|
||
|
||
|
||
**Effect on original feature:** Deletion of semantically well-defined feature[.](#2.sentence-7)
|
||
|
||
|
||
|
||
|
||
**Difficulty of converting:** Semantic transformation[.](#2.sentence-8)
|
||
|
||
If volatile semantics are required for the copy,
|
||
a user-declared constructor or assignment must
|
||
be provided[.](#2.sentence-9)
|
||
|
||
If non-volatile semantics are required,
|
||
an explicitconst_cast can be used[.](#2.sentence-10)
|
||
|
||
|
||
|
||
|
||
**How widely used:** Seldom[.](#2.sentence-11)
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L3571)
|
||
|
||
**Affected subclause:** [[class.bit]](class.bit)
|
||
|
||
|
||
**Change:** Bit-fields of type plain int are signed[.](#3.sentence-1)
|
||
|
||
|
||
|
||
|
||
**Rationale:** The signedness needs to be consistent among template specializations[.](#3.sentence-2)
|
||
|
||
For consistency,
|
||
the implementation freedom was eliminated for non-dependent types,
|
||
too[.](#3.sentence-3)
|
||
|
||
|
||
|
||
|
||
**Effect on original feature:** The choice is implementation-defined in C, but not so in C++[.](#3.sentence-4)
|
||
|
||
|
||
|
||
|
||
**Difficulty of converting:** Syntactic transformation[.](#3.sentence-5)
|
||
|
||
|
||
|
||
|
||
**How widely used:** Seldom[.](#3.sentence-6)
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L3587)
|
||
|
||
**Affected subclause:** [[class.nest]](class.nest)
|
||
|
||
|
||
**Change:** In C++, the name of a nested class is local to its enclosing class[.](#4.sentence-1)
|
||
|
||
In C
|
||
the name of the nested class belongs to the same scope as the name of the outermost enclosing class[.](#4.sentence-2)
|
||
|
||
[*Example [3](#example-3)*: struct X {struct Y { /* ... */ } y;};struct Y yy; // valid C, invalid C++ â *end example*]
|
||
|
||
|
||
|
||
|
||
**Rationale:** C++ classes have member functions which require that classes
|
||
establish scopes[.](#4.sentence-3)
|
||
|
||
The C rule would leave classes as an incomplete scope mechanism
|
||
which would prevent C++ programmers from maintaining locality
|
||
within a class[.](#4.sentence-4)
|
||
|
||
A coherent set of scope rules for C++ based on the C rule would
|
||
be very complicated and C++ programmers would be unable to predict
|
||
reliably the meanings of nontrivial examples involving nested or
|
||
local functions[.](#4.sentence-5)
|
||
|
||
|
||
|
||
|
||
**Effect on original feature:** Change to semantics of well-defined feature[.](#4.sentence-6)
|
||
|
||
|
||
|
||
|
||
**Difficulty of converting:** Semantic transformation[.](#4.sentence-7)
|
||
|
||
To make the struct type name visible in the scope of the enclosing
|
||
struct, the struct tag can be declared in the scope of the
|
||
enclosing struct, before the enclosing struct is defined[.](#4.sentence-8)
|
||
|
||
[*Example [4](#example-4)*: struct Y; // struct Y and struct X are at the same scopestruct X {struct Y { /* ... */ } y;}; â *end example*]
|
||
|
||
All the definitions of C struct types enclosed in other struct
|
||
definitions and accessed outside the scope of the enclosing
|
||
struct can be exported to the scope of the enclosing struct[.](#4.sentence-9)
|
||
|
||
Note: this is a consequence of the difference in scope rules,
|
||
which is documented in [[basic.scope]](basic.scope "6.4 Scope")[.](#4.sentence-10)
|
||
|
||
|
||
|
||
|
||
**How widely used:** Seldom[.](#4.sentence-11)
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L3634)
|
||
|
||
**Affected subclause:** [[class.member.lookup]](class.member.lookup)
|
||
|
||
|
||
**Change:** In C++, a [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") may not be redeclared in a class definition after being used in that definition[.](#5.sentence-1)
|
||
|
||
[*Example [5](#example-5)*: typedef int I;struct S { I i; int I; // valid C, invalid C++}; â *end example*]
|
||
|
||
|
||
|
||
|
||
**Rationale:** When classes become complicated, allowing such a redefinition
|
||
after the type has been used can create confusion for C++
|
||
programmers as to what the meaning of I really is[.](#5.sentence-2)
|
||
|
||
|
||
|
||
|
||
**Effect on original feature:** Deletion of semantically well-defined feature[.](#5.sentence-3)
|
||
|
||
|
||
|
||
|
||
**Difficulty of converting:** Semantic transformation[.](#5.sentence-4)
|
||
|
||
Either the type or the struct member has to be renamed[.](#5.sentence-5)
|
||
|
||
|
||
|
||
|
||
**How widely used:** Seldom[.](#5.sentence-6)
|