Jones D.M.The new C standard (C90 and C++).An economic and cultural commentary.2005
.pdf846 |
|
6.4.4.2 Floating constants |
|
||||||
|
|
|
|
C++ |
|
||||
|
2.13.3p1 |
|
|
|
|
||||
|
The integer part, the optional decimal point and the optional fraction part form the significant part of the |
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
floating literal. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The use of the term significant may be a typo. This term does not appear in the C++ Standard and it is only |
|
|||||
|
|
|
|
used in this context in one paragraph. |
|
||||
|
|
|
|
|
|
839 |
|||
|
|
|
|
The components of the exponent part are an e, E, p, or P followed by an exponent consisting of an optionally |
|||||
|
|
|
|
signed digit sequence. |
|
||||
|
|
|
|
C90 |
|
||||
|
|
|
|
Support for p and P is new in C99. |
|
||||
|
|
|
|
C++ |
|
||||
|
|
|
|
|
|||||
|
|
|
|
Like C90, the C++ Standard does not support the use of p, or P. |
|
||||
|
|
Semantics |
|
||||||
|
|
|
|
|
|
842 |
|||
|
|
|
|
The significand part is interpreted as a (decimal or hexadecimal) rational number; |
|||||
|
|
|
|
C90 |
|
||||
|
|
|
|
Support for hexadecimal significands is new in C99. |
|
||||
|
|
|
|
C++ |
|
||||
|
|
|
|
|
|||||
|
|
|
|
The C++ Standard does not support hexadecimal significands, which are new in C99. |
|
||||
|
|
|
|
|
|
843 |
|||
|
|
|
|
the digit sequence in the exponent part is interpreted as a decimal integer. |
|||||
|
|
|
|
C++ |
|
||||
|
2.13.3p1 |
|
|
|
|||||
|
. . . , an optionally signed integer exponent, . . . |
|
|||||||
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|||
|
|
|
There is no requirement that this integer exponent be interpreted as a decimal integer. Although there is |
|
|||||
|
|
|
wording specifying that both the integer and fraction parts are in base 10, there is no such wording for the |
|
|||||
|
|
|
|
exponent part. It would be surprising if the C++ Standard were to interpret 1.2e011 as representing 1.2×109; |
|
||||
|
|
|
|
therefore this issue is not specified as a difference. |
|
||||
|
|
|
|
|
|
845 |
|||
|
|
|
|
For hexadecimal floating constants, the exponent indicates the power of 2 by which the significand part is to |
|||||
|
|
|
|
be scaled. |
|
floating constant representable value chosen
C90
Support for hexadecimal floating constants is new in C99.
C++
The C++ Standard does not support hexadecimal floating constants.
For decimal floating constants, and also for hexadecimal floating constants when FLT_RADIX is not a power of 846 2, the result is either the nearest representable value, or the larger or smaller representable value immediately adjacent to the nearest representable value, chosen in an implementation-defined manner.
v 1.0b |
September 2, 2005 |
6.4.4.3 Enumeration constants 856
C90
Support for hexadecimal floating constants is new in C99.
C++
2.13.3p1
If the scaled value is in the range of representable values for its type, the result is the scaled value if representable, else the larger or smaller representable value nearest the scaled value, chosen in an implementationdefined manner.
851 Floating constants are converted to internal format as if at translation-time. |
floating constant |
|
internal format |
C90
No such requirement is explicitly specified in the C90 Standard.
In C99 floating constants may convert to more range and precision than is indicated by their type; that is,
0.1f may be represented as if it had been written 0.1L. |
351 |
FLT_EVAL_ME |
|
C++ |
|
Like C90, there is no such requirement in the C++ Standard. |
|
852 The conversion of a floating constant shall not raise an exceptional condition or a floating-point exception at execution time.
C90
No such requirement was explicitly specified in the C90 Standard.
C++
Like C90, there is no such requirement in the C++ Standard.
Recommended practice
floating con-
stant conversion not raise exception
853 The implementation should produce a diagnostic message if a hexadecimal constant cannot be represented exactly in its evaluation format;
C90
Recommended practices are new in C99, as are hexadecimal floating constants.
C++
The C++ Standard does not specify support for hexadecimal floating constants.
855The translation-time conversion of floating constants should match the execution-time conversion of character strings by library functions, such as strtod, given matching inputs suitable for both conversions, the same result format, and default execution-time rounding.64)
C90
This recommendation is new in C99.
C++
No such requirement is explicitly specified in the C ++ Standard.
856 64) The specification for the library functions recommends more accurate conversion than required for floating constants (see 7.20.1.3).
hexadecimal constant not repre-
sented exactly
footnote 64
September 2, 2005 |
v 1.0b |
860 |
6.4.4.4 Character constants |
|
|||
|
C++ |
|
|||
|
There observation is not made in the C++ Standard. The C++ Standard includes the C library by reference, |
|
|||
|
so by implication this statement is also true in C++. |
|
|||
|
6.4.4.3 Enumeration constants |
|
|||
enumera- |
|
|
|
|
|
tion constant |
857 |
||||
syntax |
|
|
|
|
enumeration-constant: identifier
C++
enumeration constant type
The C++ syntax uses the terminator enumerator.
Semantics
|
|
An identifier declared as an enumeration constant has type int. |
858 |
||
|
|
C++ |
|
||
7.2p4 |
|
|
|
||
|
Following the closing brace of an enum-specifier, each enumerator has the type of its enumeration. Prior to |
|
|
||
|
|
|
the closing brace, the type of each enumerator is the type of its initializing value. If an initializer is specified |
|
|
|
|
|
for an enumerator, the initializing value has the same type as the expression. If no initializer is specified for |
|
|
|
|
|
the first enumerator, the type is an unspecified integral type. Otherwise the type is the same as the type of the |
|
|
|
|
|
initializing value of the preceding enumerator unless the incremented value is not representable in that type, in |
|
|
|
|
|
which case the type is an unspecified integral type sufficient to contain the incremented value. |
|
|
|
|
|
|
|
|
|
|
This is quite a complex set of rules. The most interesting consequence of them is that each enumerator, in |
|
||
|
|
the same type definition, can have a different type (at least while the enumeration is being defined): |
|
||
|
|
|
|||
|
|
In C the type of the enumerator is always int. In C++ it can vary, on an enumerator by enumerator basis, |
|
||
|
|
for the same type definition. This difference only becomes visible if an initializing value uses the sizeof |
|
||
|
|
operator applied to a prior enumerator from the current declaration. |
|
||
|
|
|
|
|
|
1#include <limits.h>
2 |
|
|
|
|
|
|
3 |
enum TAG { |
E1 |
= 2L, |
// E1 |
has type |
long |
4 |
|
E2 |
= sizeof(E1), |
// E2 |
has type |
size_t, value sizeof(long) |
5 |
|
E3 |
= 9, |
// E3 |
has type |
int |
6 |
|
E4 |
= ’4’, |
// E4 |
has type |
char |
7 |
|
E5 |
= INT_MAX, |
// E5 |
has type int |
|
8 |
|
E6, |
|
// is |
E6 an unsigned int, or a long? |
|
9 |
|
E7 |
= sizeof(E4), |
// E2 |
has type size_t, value sizeof(char) |
|
10 |
} |
|
|
// final type is decided when the } is encountered |
||
11 |
|
e_val; |
|
|
|
|
12 |
|
|
|
|
|
|
13int probably_a_C_translator(void)
14{
15return (E2 == E7);
16}
Source developed using a C++ translator may contain enumeration with values that would cause a constraint violation if processed by a C translator.
1#include <limits.h>
2
3enum TAG { E1 = LONG_MAX }; /* Constraint violation if LONG_MAX != INT_MAX */
6.4.4.4 Character constants
v 1.0b |
September 2, 2005 |
6.4.4.4 Character constants 863
860
character-constant:
’ c-char-sequence ’ L’ c-char-sequence ’
c-char-sequence:
c-char c-char-sequence c-char
c-char:
any member of the source character set except
the single-quote ’, backslash \, or new-line character escape-sequence
escape-sequence:
simple-escape-sequence octal-escape-sequence hexadecimal-escape-sequence universal-character-name
simple-escape-sequence: one of
\’ \" \? \\
\a \b \f \n \r \t \v octal-escape-sequence:
\octal-digit
\octal-digit octal-digit
\octal-digit octal-digit octal-digit
hexadecimal-escape-sequence:
\x hexadecimal-digit hexadecimal-escape-sequence hexadecimal-digit
character constant
syntax escape sequence
syntax
C90
Support for universal-character-name is new in C99.
C++
The C++ Standard classifies universal-character-name as an escape-sequence, not as a c-char. This makes no difference in practice to the handling of such c-chars.
Description
861 An integer character constant is a sequence of one or more multibyte characters enclosed in single-quotes, as in ’x’.
C90
The example of ab as an integer character constant has been removed from the C99 description.
C++
integer char-
acter constant character
constant is sequence of
A character literal is one or more characters enclosed in single quotes, as in ’x’, . . . |
2.13.2p1 |
|
|
A multibyte character is replaced by a universal-character-name in C++ translation phase 1. So, the C++ Standard does not need to refer to such entities here.
September 2, 2005 |
v 1.0b |
872 6.4.4.4 Character constants
With a few exceptions detailed later, the elements of the sequence are any members of the source character 863 set;
C++
2.13.2p5
character constant mapped
2.13.2p1
2.2p3
2.13.2p2
escape sequences
character con-
stant character
constant escape se-
quences
[Note: in translation phase 1, a universal-character-name is introduced whenever an actual extended character is encountered in the source text. Therefore, all extended characters are described in terms of universal-character-names. However, the actual compiler implementation may use its own native character set, so long as the same results are obtained. ]
In C++ all elements in the sequence are characters in the source character set after translation phase 1. The creation of character-literal preprocessing tokens occurs in translation phase 3, rendering this statement not applicable to C++.
they are mapped in an implementation-defined manner to members of the execution character set. |
864 |
|||||
C++ |
|
|
|
|
|
|
|
|
|
|
|||
|
An ordinary character literal that contains a single c-char has type char, with value equal to the numerical |
|
|
|
||
|
value of the encoding of the c-char in the execution character set. |
|
|
|
||
|
|
|
|
|
||
|
|
|
|
|||
|
The values of the members of the execution character sets are implementation-defined, . . . |
|
|
|
||
|
|
|
|
|
||
|
|
|
|
|||
|
The value of a wide-character literal containing a single c-char has value equal to the numerical value of the |
|
|
|
||
|
encoding of the c-char in the execution wide-character set. |
|
|
|
||
|
|
|
|
|
||
Taken together, these statements have the same meaning as the C specification. |
|
|||||
|
|
|
||||
The single-quote ’, the double-quote ", the question-mark ?, the backslash \, and arbitrary integer values |
865 |
|||||
are representable according to the following table of escape sequences: |
|
|||||
single quote |
’ |
\’ |
|
|||
double quote |
" |
\" |
|
|
|
|
question mark |
? |
\? |
|
|
|
|
backslash |
\ |
\\ |
|
|
|
|
octal character |
|
\octal digits |
|
|||
hexadecimal character |
\xhexadecimal digits |
|
C++
The C++ wording, in Clause 2.13.2p3, does discuss arbitrary integer values and the associated Table 5 includes all of the defined escape sequences.
In addition, characters not in the basic character set are representable by universal character names and 872
certain nongraphic characters are representable by escape sequences consisting of the backslash \ followed by a lowercase letter: \a, \b, \f, \n, \r, \t, and \v.65)
v 1.0b |
September 2, 2005 |