Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Jones D.M.The new C standard (C90 and C++).An economic and cultural commentary.2005

.pdf
Скачиваний:
19
Добавлен:
23.08.2013
Размер:
1.36 Mб
Скачать

1354 6.7.1 Storage-class specifiers

3.1p2

declaration specifiers

C++

A declaration is a definition unless . . . , or it is a typedef declaration (7.1.3), . . .

A typedef name is not considered to be a definition in C ++. However, this difference does not cause any C compatibility consequences. Enumerations constants are not explicitly excluded in the unless list. They are thus definitions.

The declaration specifiers consist of a sequence of specifiers that indicate the linkage, storage duration, and 1347 part of the type of the entities that the declarators denote.

declarator list of

C++

The C++ Standard does not make this observation.

The init-declarator-list is a comma-separated sequence of declarators, each of which may have additional 1348 type information, or an initializer, or both.

C++

object

type complete by end

The C++ Standard does not make this observation.

If an identifier for an object is declared with no linkage, the type for the object shall be complete by the end 1351 of its declarator, or by the end of its init-declarator if it has an initializer;

C++

3.1p6

A program is ill-formed if the definition of any object gives the object an incomplete type (3.9).

The C++ wording covers all of the cases covered by the C specification above.

A violation of this requirement must be diagnosed by a conforming C++ translator. There is no such requirement on a C translator. However, it is very unlikely that a C implementation will not issue a diagnostic in this case (perhaps because of some extension being available).

in the case of function arguments (including in prototypes), it is the adjusted type (see 6.7.5.3) that is required 1352 to be complete.

C90

This wording was added to the C99 Standard to clarify possible ambiguities in the order in which requirements, in the standard, were performed on parameters that were part of a function declaration; for instance, int f(int a[]);.

C++

The nearest the C++ Standard comes to specifying such a rule is:

5.2.2p4

When a function is called, the parameters that have object type shall have completely-defined object type. [Note: this still allows a parameter to be a pointer or reference to an incomplete class type. However, it prevents a passed-by-value parameter to have an incomplete class type. ]

6.7.1 Storage-class specifiers

v 1.0b

September 2, 2005

6.7.1 Storage-class specifiers 1359

1354

storage-class-specifier: typedef

extern static auto register

C++

The C++ Standard classifies typedef (7.1p1) as a decl-specifier, not a storage-class-specifier

(which also includes mutable, a C++ specific keyword).

Constraints

1355 At most, one storage-class specifier may be given in the declaration specifiers in a declaration. 100)

C++

storageclass specifier syntax

While the C++ Standard (7.1.1p1) contains the same requirement, it does not include typedef in the list of storage-class-specifiers. There is no wording in the C++ limiting the number of instances of the typedef decl-specifier in a declaration.

Source developed using a C++ translator may contain more than one occurrence of the typedef decl-specifier in a declaration.

Semantics

1356 The typedef specifier is called a “storage-class specifier” for syntactic convenience only;

C++

It is called a decl-specifier in the C++ Standard (7.1p1).

1359 A declaration of an identifier for an object with storage-class specifier register suggests that access to the object be as fast as possible.

C++

A register specifier has the same semantics as an auto specifier together with a hint to the implementation that the object so declared will be heavily used.

Translator implementors are likely to assume that the reason a developer provides this hint is that they are expecting the translator to make use of it to improve the performance of the generated machine code. The

register storage-class

7.1.1p3

September 2, 2005

v 1.0b

1368

6.7.2 Type specifiers

 

 

 

C++ hint does not specify implementation details. The differing interpretations given, by the two standards,

 

 

 

for hints provides to translators is not likely to be significant. The majority of modern translators ignore the

 

 

 

hint and do what they think is best.

 

 

 

 

 

 

register

 

The extent to which such suggestions are effective is implementation-defined. 101)

1360

extent effective

 

 

 

C++

 

 

 

The C++ Standard gives no status to a translators implementation of this hint (suggestion). A C++ translator

 

 

 

is not required to document its handling of the register storage-class specifier and often a developer is no

 

 

 

less wiser than if it is documented.

 

 

 

 

 

1364

 

 

However, whether or not addressable storage is actually used, the address of any part of an object declared

 

with storage-class specifier register cannot be computed, either explicitly (by use of the unary & operator

 

 

 

as discussed in 6.5.3.2) or implicitly (by converting an array name to a pointer as discussed in 6.3.2.1).

 

unary & 1078 operand

constraints

C++

This requirement does not apply in C++.

Thus, the only operator that can be applied to an array declared with storage-class specifier register is 1365 sizeof.

unary & 1078 operand

constraints

C++

This observation is not true in C++.

If an aggregate or union object is declared with a storage-class specifier other than typedef, the properties 1366 resulting from the storage-class specifier, except with respect to linkage, also apply to the members of the

object, and so on recursively for any aggregate or union member objects.

C90

This wording did not appear in the C90 Standard and was added by the response to DR #017q6.

C++

The C++ Standard does not explicitly specify the behavior in this case.

6.7.2 Type specifiers

type specifier

 

 

 

 

syntax

1368

 

 

type-specifier:

 

void

 

char

 

short

 

int

 

long

 

float

 

double

 

signed

 

unsigned

 

_Bool

 

_Complex

 

_Imaginary

 

struct-or-union-specifier

 

enum-specifier

 

typedef-name

v 1.0b

September 2, 2005

6.7.2 Type specifiers 1372

C90

Support for the type-specifiers _Bool, _Complex, and _Imaginary is new in C99.

C++

The nonterminal for these terminals is called simple-type-specifier in C++ (7.1.5.2p1). The C++ Standard does contain a nonterminal called type-specifier. It is used in a higher-level production (7.1.5p1) that includes cv-qualifier.

The C++ Standard includes wchar_t and bool (the identifier bool is defined as a macro in the header stdbool.h in C) as type-specifiers (they are keywords in C++). The C++ Standard does not include _Bool, _Complex and _Imaginary, either as keywords or type specifiers.

Constraints

1369 At least one type specifier shall be given in the declaration specifiers in each declaration, and in the specifierqualifier list in each struct declaration and type name.

C90

This requirement is new in C99.

In C90 an omitted type-specifier implied the type specifier int. Translating a source file that contains such a declaration will cause a diagnostic to be issued and are no longer considered conforming programs.

declaration at least one type specifier

C++

 

 

 

7.1.5p2

 

At least one type-specifier that is not a cv-qualifier is required in a declaration unless it declares a

 

constructor, destructor or conversion function.80)

 

 

 

 

Although the terms used have different definitions in C/C ++, the result is the same.

1372

--~ void --~ char

--~ signed char --~ unsigned char

--~ short, signed short, short int, or signed short int --~ unsigned short, or unsigned short int

--~ int, signed, or signed int --~ unsigned, or unsigned int

--~ long, signed long, long int, or signed long int --~ unsigned long, or unsigned long int

--~ long long, signed long long, long long int, or signed long long int --~ unsigned long long, or unsigned long long int

--~ float --~ double

--~ long double --~ _Bool

--~ float _Complex --~ double _Complex

--~ long double _Complex --~float _Imaginary --~double _Imaginary --~long double _Imaginary

--~ struct or union specifier --~ enum specifier

--~ typedef name

type specifiers possible sets of

September 2, 2005

v 1.0b

7
8
1 extern x;

1378 6.7.2 Type specifiers

C90

Support for the following is new in C99:

long long, signed long long, long long int, or signed long long int

unsigned long long, or unsigned long long int

_Bool

float _Complex

double _Complex

long double _Complex

Support for the no type specifiers set, in the int, signed, signed int list has been removed in C99.

/* strictly conforming C90 */

2/* constraint violation C99 */

3 const y;

/* strictly conforming C90 */

4/* constraint violation C99 */

5

z;

/* strictly conforming C90 */

6/* constraint violation C99 */

f(); /* strictly conforming C90 */ /* constraint violation C99 */

bit-field int

C++

The list of combinations, given above as being new in C99 are not supported by C++.

Like C99, the C++ Standard does not require a translator to provide an implicit function declaration returning int (footnote 80) being supplied for a missing type specifier.

The type specifier s _Complex and _Imaginary shall not be used if the implementation does not provide those 1373 complex types.102)

C90

Support for this type specifier is new in C99.

C++

Support for these type specifiers is new in C99 and are not specified as such in the C ++ Standard. The header <complex> defines template classes and associated operations whose behavior provides the same functionality as that provided, in C, for objects declared to have type _Complex. There are no equivalent definitions for _Imaginary.

Semantics

Each of the comma-separated sets designates the same type, except that for bit-fields, it is implementation- 1377 defined whether the specifier int designates the same type as signed int or the same type as unsigned

int.

C90

Each of the above comma-separated sets designates the same type, except that for bit-fields, the type signed int (or signed) may differ from int (or no type specifiers).

C++

Rather than giving a set of possibilities, the C++ Standard lists each combination of specifiers and its associated type (Table 7).

v 1.0b

September 2, 2005

6.7.2.1 Structure and union specifiers 1381

footnote

102

1378 102) 101)Implementations are not required to provide imaginary types. Freestanding implementations are

not required to provide complex types.

C90

Support for complex types is new in C99.

C++

There is no specification for imaginary types (in the <complex> header or otherwise) in the C++ Standard.

6.7.2.1 Structure and union specifiers

1380

struct-or-union-specifier:

struct-or-union identifieropt { struct-declaration-list } struct-or-union identifier

struct-or-union:

struct union

struct-declaration-list: struct-declaration

struct-declaration-list struct-declaration struct-declaration:

specifier-qualifier-list struct-declarator-list ; specifier-qualifier-list:

type-specifier specifier-qualifier-listopt type-qualifier specifier-qualifier-listopt

struct-declarator-list: struct-declarator

struct-declarator-list , struct-declarator struct-declarator:

declarator

declaratoropt : constant-expression

C++

The C++ Standard uses the general term class to refer to these constructs. This usage is also reflected in naming of the nonterminals in the C++ syntax. The production struct-or-union is known as class-key in C++ and also includes the keyword class. The form that omits the brace enclosed list of members is known as an elaborated-type-specifier (7.1.5.3) in C++.

Constraints

1381 A structure or union shall not contain a member with incomplete or function type (hence, a structure shall not contain an instance of itself, but may contain a pointer to an instance of itself), except that the last member of a structure with more than one named member may have incomplete array type;

C90

Support for the exception on the last named member is new in C99.

C++

It is a design feature of C++ that class types can contain incomplete and function types. Source containing instances of such constructs is making use of significant features of C ++ and there is unlikely to be any expectation of being able to successfully process it using a C translator.

The exception on the last named member is new in C99 and this usage is not supported in the C++ Standard.

The following describes a restriction in C++ that does not apply in C.

struct/union syntax

member not types

September 2, 2005

v 1.0b

annex C.1.7p3

 

1385 6.7.2.1 Structure and union specifiers

bit-field maximum width

Change: In C++, a typedef name may not be redefined in a class declaration after being used in the declaration

Example:

typedef int I; struct S {

I i;

int I; // valid C, invalid C++ };

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.

The expression that specifies the width of a bit-field shall be an integer constant expression that has a 1383 nonnegative value that shall not exceed the numberwidth of bits in an object of the type that iswould be specified ifwere the colon and expression are omitted.

C90

The C90 wording ended with “ . . . of bits in an ordinary object of compatible type.”, which begs the question of whether bit-fields are variants of integer types or are separate types.

C++

bit-field

571

The C++ issues are discussed elsewhere.

 

value is m bits

 

 

 

 

 

1384

 

 

If the value is zero, the declaration shall have no declarator.

C++

9.6p2

Only when declaring an unnamed bit-field may the constant-expression be a value equal to zero.

Source developed using a C++ translator may contain a declaration of a zero width bit-field that include a declarator, which will generate a constraint violation if processed by a C translator.

1struct {

2int mem_1;

3

unsigned int mem_2:0; //

no

diagnostic required

 

4

/* constraint violation,

diagnostic required

*/

5

} obj;

 

 

 

There is an open C++ DR (#057) concerning the lack of a prohibition against declarations of the form:

1 union {int : 0;} x;

bit-field

A bit-field shall have a type that is a qualified or unqualified version of _Bool, signed int, unsigned int, or 1385

shall have type

some other implementation-defined type.

 

 

C90

 

The following wording appeared in a semantics clause in C90, not a constraint clause.

v 1.0b

September 2, 2005

6.7.2.1 Structure and union specifiers 1397

A bit-field shall have a type that is a qualified or unqualified version of one of int, unsigned int, or signed int.

Programs that used other types in the declaration of a bit-field exhibited undefined behavior in C90. Such programs exhibit implementation-defined behavior in C99.

C++

9.6p3

A bit-field shall have integral or enumeration type (3.9.1).

Source developed using a C++ translator may contain bit-fields declared using types that are a constraint violation if processed by a C translator.

1enum E_TAG {a, b};

2

3struct {

4 char m_1 : 3;

5short m_2 : 5;

6 long m_3 : 7;

7enum E_TAG m_4 : 9;

8} glob;

Semantics

1386 As discussed in 6.2.5, a structure is a type consisting of a sequence of members, whose storage is allocated in an ordered sequence, and a union is a type consisting of a sequence of members whose storage overlap.

C++

This requirement can be deduced from 9.2p12 and 9.5p1.

1387 Structure and union specifiers have the same form.

C++

The C++ Standard does not make this observation.

1391 If the struct-declaration-list contains no named members, the behavior is undefined.

C++

9p1

An object of a class consists of a (possibly empty) sequence of members and base class objects.

Source developed using a C++ translator may contain class types having no members. This usage will result in undefined behavior when processed by a C translator.

1393 A member of a structure or union may have any object type other than a variably modified type. 103)

struct member

 

type

C90

 

Support for variably modified types is new in C99.

C++

Support for variably modified types is new in C99 and they are not specified in the C++ Standard.

September 2, 2005

v 1.0b

1412

6.7.2.1 Structure and union specifiers

 

 

 

 

 

 

bit-field

A bit-field is interpreted as a signed or unsigned integer type consisting of the specified number of bits. 105)

1397

interpreted as

 

C++

bit-field packed into

The C++ Standard does not specify (9.6p1) that the specified number of bits is used for the value representation.

If the value 0 or 1 is stored into a nonzero-width bit-field of type _Bool, the value of the bit-field shall compare 1398 equal to the value stored.

C90

Support for the type _Bool is new in C99.

If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed 1400 into adjacent bits of the same unit.

C++

This requirement is not specified in the C ++ Standard.

9.6p1

Allocation of bit-fields within a class object is implementation-defined.

alignment

The alignment of the addressable storage unit is unspecified.

1403

addressable

C++

 

storage unit

 

footnote 103

footnote 105

member alignment

The wording in the C++ Standard refers to the bit-field, not the addressable allocation unit in which it resides. Does this wording refer to the alignment within the addressable allocation unit?

9.6p1

Alignment of bit-fields is implementation-defined. Bit-fields are packed into some addressable allocation unit.

103) A structure or union can not contain a member with a variably modified type because member names

1406

are not ordinary identifiers as defined in 6.2.3.

 

C90

 

Support for variably modified types is new in C99.

 

C++

 

Variably modified types are new in C99 and are not available in C++.

 

 

 

 

105) As specified in 6.7.2 above, if the actual type specifier used is int or a typedef-name defined as int,

1409

then it is implementation-defined whether the bit-field is signed or unsigned.

 

C90

 

This footnote is new in C99.

 

 

 

 

Each non-bit-field member of a structure or union object is aligned in an implementation-defined manner

1411

appropriate to its type.

 

C++

The C++ Standard specifies (3.9p5) that the alignment of all object types is implementation-defined.

v 1.0b

September 2, 2005

 

6.7.2.1 Structure and union specifiers

 

1419

 

 

 

 

 

 

 

 

 

 

 

1412

Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses

 

member

 

that increase in the order in which they are declared.

address in-

 

 

creasing

 

C++

 

 

 

The C++ Standard does not say anything explicit about bit-fields (9.2p12).

 

 

 

 

 

 

 

1414

There may be unnamed padding within a structure object, but not at its beginning.

 

structure

 

 

 

unnamed padding

 

C90

 

 

There may therefore be unnamed padding within a structure object, but not at its beginning, as necessary to achieve the appropriate alignment.

C++

This commentary applies to POD-struct types (9.2p17) in C++. Such types correspond to the structure types available in C.

1417 A pointer to a union object, suitably converted, points to each of its members (or if a member is a bit-field, then to the unit in which it resides), and vice versa.

C++

union members start same address

This requirement can be deduced from:

9.5p1

Each data member is allocated as if it were the sole member of a struct.

1418 There may be unnamed padding at the end of a structure or union.

structure

C++

trailing padding

 

The only time this possibility is mentioned in the C++ Standard is under the sizeof operator:

 

 

 

5.3.3p2

 

When applied to a class, the result is the number of bytes in an object of that class including any padding

 

 

 

required for placing objects of that type in an array.

 

 

 

 

1419 As a special case, the last element of a structure with more than one named member may have an incomplete array type;

C90

The issues involved in making use of the struct hack were raised in DR #051. The response pointed out declaring the member to be an array containing fewer elements and then allocating storage extra storage for additional elements was not strictly conforming. However, declaring the array to have a large number of elements and allocating storage for fewer elements was strictly conforming.

1#include <stdlib.h>

2#define HUGE_ARR 10000 /* Largest desired array. */

3

4 struct A {

September 2, 2005

v 1.0b

Соседние файлы в предмете Электротехника