c*******v 发帖数: 2599 | 1
http://www.open-std.org/jtc1/sc22/open/n2356/diff.html
______________________________________________________________________
Annex 0 (informative)
Compatibility [diff]
______________________________________________________________________
1 This Annex summarizes the evolution of C++ since the first edition of
The C++ Programming Language and explains in detail the differences
between C++ and C. Because the C language as described by this Inter-
national Standard differs from the dialects of Classic C used up till
now, we discuss the differences between C++ and ISO C as well as the
differences between C++ and Classic C.
2 C++ is based on C (K&R78) and adopts most of the changes specified by
the ISO C standard. Converting programs among C++, K&R C, and ISO C
may be subject to vicissitudes of expression evaluation. All differ-
ences between C++ and ISO C can be diagnosed by an implementation.
With the exceptions listed in this Annex, programs that are both C++
and ISO C have the same meaning in both languages.
1.1 Extensions [diff.c]
1 This subclause summarizes the major extensions to C provided by C++.
1.1.1 C++ features available in 1985 [diff.early]
1 This subclause summarizes the extensions to C provided by C++ in the
1985 version of its manual:
2 The types of function parameters can be specified (_dcl.fct_) and will
be checked (_expr.call_). Type conversions will be performed
(_expr.call_). This is also in ISO C.
3 Single-precision floating point arithmetic may be used for float
expressions; _basic.fundamental_ and _conv.double_. This is also in
ISO C.
4 Function names can be overloaded; _over_.
5 Operators can be overloaded; _over.oper_.
6 Functions can be inline substituted; _dcl.fct.spec_.
7 Data objects can be const; _dcl.type_. This is also in ISO C.
8 Objects of reference type can be declared; _dcl.ref_ and
_dcl.init.ref_.
9 A free store is provided by the new and delete operators; _expr.new_,
_expr.delete_.
10Classes can provide data hiding (_class.access_), guaranteed initial-
ization (_class.ctor_), user-defined conversions (_class.conv_), and
dynamic typing through use of virtual functions (_class.virtual_).
11The name of a class or enumeration is a type name; _class_.
12A pointer to any non-const and non-volatile object type can be
assigned to a void*; _conv.ptr_. This is also in ISO C.
13A pointer to function can be assigned to a void*; _conv.ptr_.
14A declaration within a block is a statement; _stmt.dcl_.
15Anonymous unions can be declared; _class.union_.
1.1.2 C++ features added since 1985 [diff.c++]
1 This subclause summarizes the major extensions of C++ since the 1985
version of this manual:
2 A class can have more than one direct base class (multiple inheri-
tance); _class.mi_.
3 Class members can be protected; _class.access_ .
4 Pointers to class members can be declared and used; _dcl.mptr_,
_expr.mptr.oper_.
5 Operators new and delete can be overloaded and declared for a class;
_expr.new_, _expr.delete_, _class.free_. This allows the "assignment
to this" technique for class specific storage management to be removed
to the anachronism subclause; _diff.this_.
6 Objects can be explicitly destroyed; _class.dtor_.
7 Assignment and initialization are defined as memberwise assignment and
initialization; _class.copy_.
8 The overload keyword was made redundant and moved to the anachronism
subclause; _diff.anac_.
9 General expressions are allowed as initializers for static objects;
_dcl.init_.
10Data objects can be volatile; _dcl.type_. Also in ISO C.
11Initializers are allowed for static class members; _class.static_.
12Member functions can be static; _class.static_.
13Member functions can be const and volatile; _class.this_.
14Linkage to non-C++ program fragments can be explicitly declared;
_dcl.link_.
15Operators ->, ->*, and , can be overloaded; _over.oper_.
16Classes can be abstract; _class.abstract_.
17Prefix and postfix application of ++ and -- on a user-defined type can
be distinguished.
18Templates; _temp_.
19Exception handling; _except_.
20The bool type (_basic.fundamental_).
1.2 C++ and ISO C [diff.iso]
1 The subclauses of this subclause list the differences between C++ and
ISO C, by the chapters of this document.
1.2.1 Clause _lex_: lexical conventions [diff.lex]
Subclause _lex.trigraph_
1 Change: C++ style comments (//) are added
A pair of slashes now introduce a one-line comment.
Rationale: This style of comments is a useful addition to the lan-
guage.
Effect on original feature: Change to semantics of well-defined fea-
ture. A valid ISO C expression containing a division operator fol-
lowed immediately by a C-style comment will now be treated as a C++
style comment. For example:
{
int a = 4;
int b = 8 //* divide by a*/ a;
+a;
}
Difficulty of converting: Syntactic transformation. Just add white
space after the division operator.
How widely used: The token sequence //* probably occurs very seldom.
Subclause _lex.key_
2 Change: New Keywords
New keywords are added to C++; see _lex.key_.
Rationale: These keywords were added in order to implement the new
semantics of C++.
Effect on original feature: Change to semantics of well-defined fea-
ture. Any ISO C programs that used any of these keywords as
identifiers are not valid C++ programs.
Difficulty of converting: Syntactic transformation. Converting one
specific program is easy. Converting a large collection of related
programs takes more work.
How widely used: Common.
Subclause _lex.ccon_
3 Change: Type of character literal is changed from int to char
Rationale: This is needed for improved overloaded function argument
type matching. For example:
int function( int i );
int function( char c );
function( 'x' );
It is preferable that this call match the second version of function
rather than the first.
Effect on original feature: Change to semantics of well-defined fea-
ture. ISO C programs which depend on
sizeof('x') == sizeof(int)
will not work the same as C++ programs.
Difficulty of converting: Simple.
How widely used: Programs which depend upon sizeof('x') are probably
rare.
Subclause _lex.string:
4 Change: String literals made const
The type of a string literal is changed from `array of char′' to "array
of const char." The type of a wide string literal is changed from
"array of wchar_t" to "array of const wchar_t."
Rationale: This avoids calling an inappropriate overloaded function,
which might expect to be able to modify its argument.
Effect on original feature: Change to semantics of well-defined fea-
ture.
Difficulty of converting: Simple syntactic transformation, because
string literals can be converted to char*; (_conv.array_). The most
common cases are handled by a new but deprecated standard conversion:
char* p = "abc"; // valid in C, deprecated in C++
char* q = expr ? "abc" : "de"; // valid in C, invalid in C++
How widely used: Programs that have a legitimate reason to treat
string literals as pointers to potentially modifiable memory are prob-
ably rare.
1.2.2 Clause _basic_: basic concepts [diff.basic]
Subclause _basic.def_
1 Change: C++ does not have "tentative definitions" as in C
E.g., at file scope,
int i;
int i;
is valid in C, invalid in C++. This makes it impossible to define
mutually referential file-local static objects, if initializers are
restricted to the syntactic forms of C. For example,
struct X { int i; struct X *next; };
static struct X a;
static struct X b = { 0, &a };
static struct X a = { 1, &b };
Rationale: This avoids having different initialization rules for
built-in types and user-defined types.
Effect on original feature: Deletion of semantically well-defined fea-
ture.
Difficulty of converting: Semantic transformation. In C++, the ini-
tializer for one of a set of mutually-referential file-local static
objects must invoke a function call to achieve the initialization.
How widely used: Seldom.
Subclause _basic.scope_
2 Change: A struct is a scope in C++, not in C
Rationale: Class scope is crucial to C++, and a struct is a class.
Effect on original feature: Change to semantics of well-defined fea-
ture.
Difficulty of converting: Semantic transformation.
How widely used: C programs use struct extremely frequently, but the
change is only noticeable when struct, enumeration, or enumerator
names are referred to outside the struct. The latter is probably
rare.
Subclause _basic.link_ [also _dcl.type_]
3 Change: A name of file scope that is explicitly declared const, and
not explicitly declared extern, has internal linkage, while in C it
would have external linkage
Rationale: Because const objects can be used as compile-time values in
C++, this feature urges programmers to provide explicit initializer
values for each const. This feature allows the user to put const
objects in header files that are included in many compilation units.
Effect on original feature: Change to semantics of well-defined fea-
ture.
Difficulty of converting: Semantic transformation
How widely used: Seldom
Subclause _basic.start_
4 Change: Main cannot be called recursively and cannot have its address
taken
Rationale: The main function may require special actions.
Effect on original feature: Deletion of semantically well-defined
feature
Difficulty of converting: Trivial: create an intermediary function
such as mymain(argc, argv).
How widely used: Seldom
Subclause _basic.types_
5 Change: C allows "compatible types" in several places, C++ does not
For example, otherwise-identical struct types with different tag names
are "compatible" in C but are distinctly different types in C++.
Rationale: Stricter type checking is essential for C++.
Effect on original feature: Deletion of semantically well-defined fea-
ture.
Difficulty of converting: Semantic transformation The "typesafe link-
age" mechanism will find many, but not all, of such problems. Those
problems not found by typesafe linkage will continue to function prop-
erly, according to the "layout compatibility rules" of this Interna-
tional Standard.
How widely used: Common.
Subclause _conv.ptr_
6 Change: Converting void* to a pointer-to-object type requires casting
char a[10];
void *b=a;
void foo() {
char *c=b;
}
ISO C will accept this usage of pointer to void being assigned to a
pointer to object type. C++ will not.
Rationale: C++ tries harder than C to enforce compile-time type
safety.
Effect on original feature: Deletion of semantically well-defined fea-
ture.
Difficulty of converting: Could be automated. Violations will be
diagnosed by the C++ translator. The fix is to add a cast. For exam-
ple:
char *c = (char *) b;
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 ISO C translators will give a warning if the cast is not
used.
Subclause _conv.ptr_
7 Change: Only pointers to non-const and non-volatile objects may be
implicitly converted to void*
Rationale: This improves type safety.
Effect on original feature: Deletion of semantically well-defined fea-
ture.
Difficulty of converting: Could be automated. A C program containing
such an implicit conversion from (e.g.) pointer-to-const-object to
void* will receive a diagnostic message. The correction is to add an
explicit cast.
How widely used: Seldom.
1.2.3 Clause _expr_: expressions [diff.expr]
Subclause _expr.call_
1 Change: Implicit declaration of functions is not allowed
Rationale: The type-safe nature of C++.
Effect on original feature: Deletion of semantically well-defined fea-
ture. Note: the original feature was labeled as "obsolescent" in ISO
C.
Difficulty of converting: Syntactic transformation. Facilities for
producing explicit function declarations are fairly widespread commer-
cially.
How widely used: Common.
Subclause _expr.sizeof_, _expr.cast_
2 Change: Types must be declared in declarations, not in expressions
In C, a sizeof expression or cast expression may create a new type.
For example,
p = (void*)(struct x {int i;} *)0;
declares a new type, struct x .
Rationale: This prohibition helps to clarify the location of declara-
tions in the source code.
Effect on original feature: Deletion of a semantically well-defined
feature.
Difficulty of converting: Syntactic transformation.
How widely used: Seldom.
1.2.4 Clause _stmt.stmt_: statements [diff.stat]
Subclause _stmt.switch_, _stmt.goto_ (switch and goto statements)
1 Change: It is now invalid to jump past a declaration with explicit or
implicit initializer (except across entire block not entered)
Rationale: Constructors used in initializers may allocate resources
which need to be de-allocated upon leaving the block. Allowing jump
past initializers would require complicated run-time determination of
allocation. Furthermore, any use of the uninitialized object could be
a disaster. With this simple compile-time rule, C++ assures that if
an initialized variable is in scope, then it has assuredly been ini-
tialized.
Effect on original feature: Deletion of semantically well-defined fea-
ture.
Difficulty of converting: Semantic transformation.
How widely used: Seldom.
Subclause _stmt.return_
2 Change: It is now invalid to return (explicitly or implicitly) from a
function which is declared to return a value without actually return-
ing a value
Rationale: The caller and callee may assume fairly elaborate return-
value mechanisms for the return of class objects. If some flow paths
execute a return without specifying any value, the implementation must
embody many more complications. Besides, promising to return a value
of a given type, and then not returning such a value, has always been
recognized to be a questionable practice, tolerated only because very-
old C had no distinction between void functions and int functions.
Effect on original feature: Deletion of semantically well-defined fea-
ture.
Difficulty of converting: Semantic transformation. Add an appropriate
return value to the source code, e.g. zero.
How widely used: Seldom. For several years, many existing C implemen-
tations have produced warnings in this case.
1.2.5 Clause _dcl.dcl_: declarations [diff.dcl]
Subclause _dcl.stc_
1 Change: In C++, the static or extern specifiers can only be applied to
names of objects or functions
Using these specifiers with type declarations is illegal in C++. In
C, these specifiers are ignored when used on type declarations. Exam-
ple:
static struct S { // valid C, invalid in C++
int i;
// ...
};
Rationale: Storage class specifiers don't have any meaning when asso-
ciated with a type. In C++, class members can be defined with the
static storage class specifier. Allowing storage class specifiers on
type declarations could render the code confusing for users.
Effect on original feature: Deletion of semantically well-defined fea-
ture.
Difficulty of converting: Syntactic transformation.
How widely used: Seldom.
Subclause _dcl.typedef_
2 Change: A C++ typedef name must be different from any class type name
declared in the same scope (except if the typedef is a synonym of the
class name with the same name). In C, a typedef name and a struct tag
name declared in the same scope can have the same name (because they
have different name spaces)
Example:
typedef struct name1 { /*...*/ } name1; // valid C and C++
struct name { /*...*/ };
typedef int name; // valid C, invalid C++
Rationale: For ease of use, C++ doesn't require that a type name be
prefixed with the keywords class, struct or union when used in object
declarations or type casts. Example:
class name { /*...*/ };
name i; // i has type 'class name'
Effect on original feature: Deletion of semantically well-defined fea-
ture.
Difficulty of converting: Semantic transformation. One of the 2 types
has to be renamed.
How widely used: Seldom.
Subclause _dcl.type_ [see also _basic.link_]
3 Change: const objects must be initialized in C++ but can be left
uninitialized in C
Rationale: A const object cannot be assigned to so it must be initial-
ized to hold a useful value.
Effect on original feature: Deletion of semantically well-defined fea-
ture.
Difficulty of converting: Semantic transformation.
How widely used: Seldom.
Subclause _dcl.type_ (type specifiers)
4 Change: Banning implicit int
In C++ a decl-specifier-seq must contain a type-specifier. In the
following example, the left-hand column presents valid C; the right-
hand column presents equivalent C++:
void f(const parm); void f(const int parm);
const n = 3; const int n = 3;
main() int main()
/* ... */ /* ... */
Rationale: In C++, implicit int creates several opportunities for
ambiguity between expressions involving function-like casts and decla-
rations. Explicit declaration is increasingly considered to be proper
style. Liaison with WG14 (C) indicated support for (at least) depre-
cating implicit int in the next revision of C.
Effect on original feature: Deletion of semantically well-defined fea-
ture.
Difficulty of converting: Syntactic transformation. Could be auto-
mated.
How widely used: Common.
Subclause _dcl.enum_
5 Change: C++ objects of enumeration type can only be assigned values of
the same enumeration type. In C, objects of enumeration type can be
assigned values of any integral type
Example:
enum color { red, blue, green };
color c = 1; // valid C, invalid C++
Rationale: The type-safe nature of C++.
Effect on original feature: Deletion of semantically well-defined fea-
ture.
Difficulty of converting: Syntactic transformation. (The type error
produced by the assignment can be automatically corrected by applying
an explicit cast.)
How widely used: Common.
Subclause _dcl.enum_
6 Change: In C++, the type of an enumerator is its enumeration. In C,
the type of an enumerator is int.
Example:
enum e { A };
sizeof(A) == sizeof(int) // in C
sizeof(A) == sizeof(e) // in C++
/* and sizeof(int) is not necessary equal to sizeof(e) */
Rationale: In C++, an enumeration is a distinct type.
Effect on original feature: Change to semantics of well-defined fea-
ture.
Difficulty of converting: Semantic transformation.
How widely used: Seldom. The only time this affects existing C code
is when the size of an enumerator is taken. Taking the size of an
enumerator is not a common C coding practice.
1.2.6 Clause _dcl.decl_: declarators [diff.decl]
Subclause _dcl.fct_
1 Change: In C++, a function declared with an empty parameter list takes
no arguments.
In C, an empty parameter list means that the number and type of the
function arguments are unknown" Example:
int f(); // means int f(void) in C++
// int f(unknown) in C
Rationale: This is to avoid erroneous function calls (i.e. function
calls with the wrong number or type of arguments).
Effect on original feature: Change to semantics of well-defined fea-
ture. This feature was marked as "obsolescent" in C.
Difficulty of converting: Syntactic transformation. The function dec-
larations using C incomplete declaration style must be completed to
become full prototype declarations. A program may need to be updated
further if different calls to the same (non-prototype) function have
different numbers of arguments or if the type of corresponding argu-
ments differed.
How widely used: Common.
Subclause _dcl.fct_ [see _expr.sizeof_]
2 Change: In C++, types may not be defined in return or parameter types.
In C, these type definitions are allowed
Example:
void f( struct S { int a; } arg ) {} // valid C, invalid C++
enum E { A, B, C } f() {} // valid C, invalid C++
Rationale: When comparing types in different compilation units, C++
relies on name equivalence when C relies on structural equivalence.
Regarding parameter types: since the type defined in an parameter list
would be in the scope of the function, the only legal calls in C++
would be from within the function itself.
Effect on original feature: Deletion of semantically well-defined fea-
ture.
Difficulty of converting: Semantic transformation. The type defini-
tions must be moved to file scope, or in header files.
How widely used: Seldom. This style of type definitions is seen as
poor coding style.
Subclause _dcl.fct.def_
3 Change: In C++, the syntax for function definition excludes the "old-
style" C function. In C, "old-style" syntax is allowed, but deprecated
as "obsolescent."
Rationale: Prototypes are essential to type safety.
Effect on original feature: Deletion of semantically well-defined fea-
ture.
Difficulty of converting: Syntactic transformation.
How widely used: Common in old programs, but already known to be obso-
lescent.
Subclause _dcl.init.string_
4 Change: In C++, when initializing an array of character with a string,
the number of characters in the string (including the terminating
' |
|