(Primitive Types): Many cleanups.
This commit is contained in:
parent
52c0123371
commit
778ce9a752
126
c.texi
126
c.texi
|
@ -1829,9 +1829,9 @@ Arithmetic operators in C attempt to be as similar as possible to the
|
||||||
abstract arithmetic operations, but it is impossible to do this
|
abstract arithmetic operations, but it is impossible to do this
|
||||||
perfectly. Numbers in a computer have a finite range of possible
|
perfectly. Numbers in a computer have a finite range of possible
|
||||||
values, and non-integer values have a limit on their possible
|
values, and non-integer values have a limit on their possible
|
||||||
accuracy. Nonetheless, in most cases you will encounter no surprises
|
accuracy. Nonetheless, except when results are out of range, you will
|
||||||
in using @samp{+} for addition, @samp{-} for subtraction, and @samp{*}
|
encounter no surprises in using @samp{+} for addition, @samp{-} for
|
||||||
for multiplication.
|
subtraction, and @samp{*} for multiplication.
|
||||||
|
|
||||||
Each C operator has a @dfn{precedence}, which is its rank in the
|
Each C operator has a @dfn{precedence}, which is its rank in the
|
||||||
grammatical order of the various operators. The operators with the
|
grammatical order of the various operators. The operators with the
|
||||||
|
@ -2102,19 +2102,19 @@ But sometimes it matters precisely where the conversion occurs.
|
||||||
|
|
||||||
If @code{i} and @code{j} are integers, @code{(i + j) * 2.0} adds them
|
If @code{i} and @code{j} are integers, @code{(i + j) * 2.0} adds them
|
||||||
as an integer, then converts the sum to floating point for the
|
as an integer, then converts the sum to floating point for the
|
||||||
multiplication. If the addition gets an overflow, that is not
|
multiplication. If the addition causes an overflow, that is not
|
||||||
equivalent to converting both integers to floating point and then
|
equivalent to converting each integer to floating point and then
|
||||||
adding them. You can get the latter result by explicitly converting
|
adding the two floating point numbers. You can get the latter result
|
||||||
the integers, as in @code{((double) i + (double) j) * 2.0}.
|
by explicitly converting the integers, as in @code{((double) i +
|
||||||
@xref{Explicit Type Conversion}.
|
(double) j) * 2.0}. @xref{Explicit Type Conversion}.
|
||||||
|
|
||||||
@c Eggert's report
|
@c Eggert's report
|
||||||
Adding or multiplying several values, including some integers and some
|
Adding or multiplying several values, including some integers and some
|
||||||
floating point, does the operations left to right. Thus, @code{3.0 +
|
floating point, performs the operations left to right. Thus, @code{3.0 +
|
||||||
i + j} converts @code{i} to floating point, then adds 3.0, then
|
i + j} converts @code{i} to floating point, then adds 3.0, then
|
||||||
converts @code{j} to floating point and adds that. You can specify a
|
converts @code{j} to floating point and adds that. You can specify a
|
||||||
different order using parentheses: @code{3.0 + (i + j)} adds @code{i}
|
different order using parentheses: @code{3.0 + (i + j)} adds @code{i}
|
||||||
and @code{j} first and then adds that result (converting to floating
|
and @code{j} first and then adds that sum (converted to floating
|
||||||
point) to 3.0. In this respect, C differs from other languages, such
|
point) to 3.0. In this respect, C differs from other languages, such
|
||||||
as Fortran.
|
as Fortran.
|
||||||
|
|
||||||
|
@ -2271,7 +2271,7 @@ The left operand is the value to be shifted, and the right operand
|
||||||
says how many bits to shift it (the @dfn{shift count}). The left
|
says how many bits to shift it (the @dfn{shift count}). The left
|
||||||
operand is promoted (@pxref{Operand Promotions}), so shifting never
|
operand is promoted (@pxref{Operand Promotions}), so shifting never
|
||||||
operates on a narrow integer type; it's always either @code{int} or
|
operates on a narrow integer type; it's always either @code{int} or
|
||||||
wider. The value of the shift operator has the same type as the
|
wider. The result of the shift operation has the same type as the
|
||||||
promoted left operand.
|
promoted left operand.
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
|
@ -2322,12 +2322,12 @@ number of bits gives machine-dependent results.
|
||||||
@subsection Caveats for Shift Operations
|
@subsection Caveats for Shift Operations
|
||||||
|
|
||||||
@strong{Warning:} If the shift count is greater than or equal to the
|
@strong{Warning:} If the shift count is greater than or equal to the
|
||||||
width in bits of the first operand, the results are machine-dependent.
|
width in bits of the promoted first operand, the results are
|
||||||
Logically speaking, the ``correct'' value would be either -1 (for
|
machine-dependent. Logically speaking, the ``correct'' value would be
|
||||||
right shift of a negative number) or 0 (in all other cases), but what
|
either @minus{}1 (for right shift of a negative number) or 0 (in all other
|
||||||
it really generates is whatever the machine's shift instruction does in
|
cases), but the actual result is whatever the machine's shift
|
||||||
that case. So unless you can prove that the second operand is not too
|
instruction does in that case. So unless you can prove that the
|
||||||
large, write code to check it at run time.
|
second operand is not too large, write code to check it at run time.
|
||||||
|
|
||||||
@strong{Warning:} Never rely on how the shift operators relate in
|
@strong{Warning:} Never rely on how the shift operators relate in
|
||||||
precedence to other arithmetic binary operators. Programmers don't
|
precedence to other arithmetic binary operators. Programmers don't
|
||||||
|
@ -3302,11 +3302,12 @@ on the left and one on the right.
|
||||||
|
|
||||||
All the binary operators in C are syntactically left-associative.
|
All the binary operators in C are syntactically left-associative.
|
||||||
This means that @w{@code{a @var{op} b @var{op} c}} means @w{@code{(a
|
This means that @w{@code{a @var{op} b @var{op} c}} means @w{@code{(a
|
||||||
@var{op} b) @var{op} c}}. However, you should only write repeated
|
@var{op} b) @var{op} c}}. However, the only operators you should
|
||||||
operators without parentheses using @samp{+}, @samp{-}, @samp{*} and
|
repeat in this way without parentheses are @samp{+}, @samp{-},
|
||||||
@samp{/}, because those cases are clear from algebra. So it is ok to
|
@samp{*} and @samp{/}, because those cases are clear from algebra. So
|
||||||
write @code{a + b + c} or @code{a - b - c}, but never @code{a == b ==
|
it is ok to write @code{a + b + c} or @code{a - b - c}, but never
|
||||||
c} or @code{a % b % c}.
|
@code{a == b == c} or @code{a % b % c}. For those operators, use
|
||||||
|
explicit parentheses to show how the operations nest.
|
||||||
|
|
||||||
Each C operator has a @dfn{precedence}, which is its rank in the
|
Each C operator has a @dfn{precedence}, which is its rank in the
|
||||||
grammatical order of the various operators. The operators with the
|
grammatical order of the various operators. The operators with the
|
||||||
|
@ -3522,7 +3523,7 @@ carried out before calling the function.
|
||||||
The ordering imposed by a sequence point applies locally to a limited
|
The ordering imposed by a sequence point applies locally to a limited
|
||||||
range of code, as stated above in each case. For instance, the
|
range of code, as stated above in each case. For instance, the
|
||||||
ordering imposed by the comma operator does not apply to code outside
|
ordering imposed by the comma operator does not apply to code outside
|
||||||
that comma operator. Thus, in this code,
|
the operands of that comma operator. Thus, in this code,
|
||||||
|
|
||||||
@example
|
@example
|
||||||
(x = 5, foo (x)) + x * x
|
(x = 5, foo (x)) + x * x
|
||||||
|
@ -3538,11 +3539,11 @@ them.
|
||||||
@cindex postincrement and ordering
|
@cindex postincrement and ordering
|
||||||
@cindex ordering and postincrement
|
@cindex ordering and postincrement
|
||||||
|
|
||||||
Ordering requirements are loose with the postincrement and
|
The ordering requirements for the postincrement and postdecrement
|
||||||
postdecrement operations (@pxref{Postincrement/Postdecrement}), which
|
operations (@pxref{Postincrement/Postdecrement}) are loose: those side
|
||||||
specify side effects to happen ``a little later.'' They must happen
|
effects must happen ``a little later,'' before the next sequence
|
||||||
before the next sequence point, but that still leaves room for various
|
point. That still leaves room for various orders that give different
|
||||||
meanings. In this expression,
|
results. In this expression,
|
||||||
|
|
||||||
@example
|
@example
|
||||||
z = x++ - foo ()
|
z = x++ - foo ()
|
||||||
|
@ -3561,11 +3562,16 @@ x = x++
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
@code{x} will certainly be incremented but the incremented value may
|
@code{x} will certainly be incremented but the incremented value may
|
||||||
not stick. If the incrementation of @code{x} happens after the
|
be replaced with the old value. That's because the incrementation and
|
||||||
assignment to @code{x}, the incremented value will remain in place.
|
the assignment may occur in either oder. If the incrementation of
|
||||||
But if the incrementation happens first, the assignment will overwrite
|
@code{x} occurs after the assignment to @code{x}, the incremented
|
||||||
that with the not-yet-incremented value, so the expression as a whole
|
value will remain in place. But if the incrementation happens first,
|
||||||
will leave @code{x} unchanged.
|
the assignment will put the not-yet-incremented value back into
|
||||||
|
@code{x}, so the expression as a whole will leave @code{x} unchanged.
|
||||||
|
|
||||||
|
The conclusion: @strong{avoid such expressions}. Take care, when you
|
||||||
|
use postincrement and postdecrement, that the specific expression you
|
||||||
|
use is not ambiguous as to order of execution.
|
||||||
|
|
||||||
@node Ordering of Operands
|
@node Ordering of Operands
|
||||||
@section Ordering of Operands
|
@section Ordering of Operands
|
||||||
|
@ -3583,14 +3589,15 @@ followed by the other. Any side effects in the operand that's computed
|
||||||
first are executed before the other operand is computed.
|
first are executed before the other operand is computed.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
That applies to assignment operators too, except that in simple assignment
|
That applies to assignment operators too, except that, in simple assignment,
|
||||||
the previous value of the left operand is unused.
|
the previous value of the left operand is unused.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
The arguments in a function call can be computed in any order, but
|
The arguments in a function call can be computed in any order, but
|
||||||
they can't be intermixed. Thus, one argument is fully computed, then
|
they can't be intermixed. Thus, one argument is fully computed, then
|
||||||
another, and so on until they are all done. Any side effects in one argument
|
another, and so on until they have all been done. Any side effects in
|
||||||
are executed before computation of another argument begins.
|
one argument are executed before computation of another argument
|
||||||
|
begins.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
These rules don't cover side effects caused by postincrement and
|
These rules don't cover side effects caused by postincrement and
|
||||||
|
@ -3598,11 +3605,11 @@ postdecrement operators---those can be deferred up to the next
|
||||||
sequence point.
|
sequence point.
|
||||||
|
|
||||||
If you want to get pedantic, the fact is that GCC can reorder the
|
If you want to get pedantic, the fact is that GCC can reorder the
|
||||||
computations in many other ways provided that doesn't alter the result
|
computations in many other ways provided that it doesn't alter the result
|
||||||
of running the program. However, because they don't alter the result
|
of running the program. However, because it doesn't alter the result
|
||||||
of running the program, they are negligible, unless you are concerned
|
of running the program, it is negligible, unless you are concerned
|
||||||
with the values in certain variables at various times as seen by other
|
with the values in certain variables at various times as seen by other
|
||||||
processes. In those cases, you can use @code{volatile} to prevent
|
processes. In those cases, you should use @code{volatile} to prevent
|
||||||
optimizations that would make them behave strangely. @xref{volatile}.
|
optimizations that would make them behave strangely. @xref{volatile}.
|
||||||
|
|
||||||
@node Optimization and Ordering
|
@node Optimization and Ordering
|
||||||
|
@ -3694,8 +3701,8 @@ represent both positive and negative numbers, in a range spread almost
|
||||||
equally on both sides of zero.
|
equally on both sides of zero.
|
||||||
|
|
||||||
Aside from signedness, the integer data types vary in size: how many
|
Aside from signedness, the integer data types vary in size: how many
|
||||||
bytes long they are. The size determines how many different integer
|
bytes long they are. The size determines the range of integer values
|
||||||
values the type can hold.
|
the type can hold.
|
||||||
|
|
||||||
Here's a list of the signed integer data types, with the sizes they
|
Here's a list of the signed integer data types, with the sizes they
|
||||||
have on most computers. Each has a corresponding unsigned type; see
|
have on most computers. Each has a corresponding unsigned type; see
|
||||||
|
@ -3704,7 +3711,8 @@ have on most computers. Each has a corresponding unsigned type; see
|
||||||
@table @code
|
@table @code
|
||||||
@item signed char
|
@item signed char
|
||||||
One byte (8 bits). This integer type is used mainly for integers that
|
One byte (8 bits). This integer type is used mainly for integers that
|
||||||
represent characters, as part of arrays or other data structures.
|
represent characters, usually as elements of arrays or fields of other
|
||||||
|
data structures.
|
||||||
|
|
||||||
@item short
|
@item short
|
||||||
@itemx short int
|
@itemx short int
|
||||||
|
@ -3775,8 +3783,8 @@ In particular, if the value is really a character, you should declare
|
||||||
the variable @code{int}. Not @code{char}! Using that narrow type can
|
the variable @code{int}. Not @code{char}! Using that narrow type can
|
||||||
force the compiler to truncate values for conversion, which is a
|
force the compiler to truncate values for conversion, which is a
|
||||||
waste. Furthermore, some functions return either a character value,
|
waste. Furthermore, some functions return either a character value,
|
||||||
or @minus{}1 for ``no character.'' Using @code{int} keeps those
|
or @minus{}1 for ``no character.'' Using @code{int} makes it possible
|
||||||
values distinct.
|
to distinguish @minus{}1 from a character by sign.
|
||||||
|
|
||||||
The narrow integer types are useful as parts of other objects, such as
|
The narrow integer types are useful as parts of other objects, such as
|
||||||
arrays and structures. Compare these array declarations, whose sizes
|
arrays and structures. Compare these array declarations, whose sizes
|
||||||
|
@ -3867,10 +3875,11 @@ given previously (@pxref{Basic Integers}).
|
||||||
|
|
||||||
To be completely sure of the size of an integer type,
|
To be completely sure of the size of an integer type,
|
||||||
use the types @code{int16_t}, @code{int32_t} and @code{int64_t}.
|
use the types @code{int16_t}, @code{int32_t} and @code{int64_t}.
|
||||||
Their corresponding unsigned types add @samp{u} at the front.
|
Their corresponding unsigned types add @samp{u} at the front:
|
||||||
To define these, include the header file @file{stdint.h}.
|
@code{uint16_t}, @code{uint32_t} and @code{uint64_t}.
|
||||||
|
To define all these types, include the header file @file{stdint.h}.
|
||||||
|
|
||||||
The GNU C Compiler compiles for some embedded controllers that use two
|
The GNU C Compiler can compile for some embedded controllers that use two
|
||||||
bytes for @code{int}. On some, @code{int} is just one ``byte,'' and
|
bytes for @code{int}. On some, @code{int} is just one ``byte,'' and
|
||||||
so is @code{short int}---but that ``byte'' may contain 16 bits or even
|
so is @code{short int}---but that ``byte'' may contain 16 bits or even
|
||||||
32 bits. These processors can't support an ordinary operating system
|
32 bits. These processors can't support an ordinary operating system
|
||||||
|
@ -3886,8 +3895,11 @@ programs do not try to support them.
|
||||||
@findex long double
|
@findex long double
|
||||||
|
|
||||||
@dfn{Floating point} is the binary analogue of scientific notation:
|
@dfn{Floating point} is the binary analogue of scientific notation:
|
||||||
internally it represents a number as a fraction and a binary exponent; the
|
internally it represents a number as a fraction and a binary exponent;
|
||||||
value is that fraction multiplied by the specified power of 2.
|
the value is that fraction multiplied by the specified power of 2.
|
||||||
|
(The C standard nominally permits other bases, but in GNU C the base
|
||||||
|
is always 2.)
|
||||||
|
@c ???
|
||||||
|
|
||||||
For instance, to represent 6, the fraction would be 0.75 and the
|
For instance, to represent 6, the fraction would be 0.75 and the
|
||||||
exponent would be 3; together they stand for the value @math{0.75 * 2@sup{3}},
|
exponent would be 3; together they stand for the value @math{0.75 * 2@sup{3}},
|
||||||
|
@ -4025,8 +4037,9 @@ print_if_positive (double x, double y)
|
||||||
@}
|
@}
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
A @code{void}-returning function is comparable to what some other languages
|
A @code{void}-returning function is comparable to what some other
|
||||||
call a ``procedure'' instead of a ``function.''
|
languages (for instance, Fortran and Pascal) call a ``procedure''
|
||||||
|
instead of a ``function.''
|
||||||
|
|
||||||
@c ??? Already presented
|
@c ??? Already presented
|
||||||
@c @samp{%f} in an output template specifies to format a @code{double} value
|
@c @samp{%f} in an output template specifies to format a @code{double} value
|
||||||
|
@ -4039,9 +4052,10 @@ Beyond the primitive types, C provides several ways to construct new
|
||||||
data types. For instance, you can define @dfn{pointers}, values that
|
data types. For instance, you can define @dfn{pointers}, values that
|
||||||
represent the addresses of other data (@pxref{Pointers}). You can
|
represent the addresses of other data (@pxref{Pointers}). You can
|
||||||
define @dfn{structures}, as in many other languages
|
define @dfn{structures}, as in many other languages
|
||||||
(@pxref{Structures}), and @dfn{unions}, which specify multiple ways
|
(@pxref{Structures}), and @dfn{unions}, which define multiple ways to
|
||||||
to look at the same memory space (@pxref{Unions}). @dfn{Enumerations}
|
interpret the contents of the same memory space (@pxref{Unions}).
|
||||||
are collections of named integer codes (@pxref{Enumeration Types}).
|
@dfn{Enumerations} are collections of named integer codes
|
||||||
|
(@pxref{Enumeration Types}).
|
||||||
|
|
||||||
@dfn{Array types} in C are used for allocating space for objects,
|
@dfn{Array types} in C are used for allocating space for objects,
|
||||||
but C does not permit operating on an array value as a whole. @xref{Arrays}.
|
but C does not permit operating on an array value as a whole. @xref{Arrays}.
|
||||||
|
@ -4053,7 +4067,7 @@ but C does not permit operating on an array value as a whole. @xref{Arrays}.
|
||||||
Some C constructs require a way to designate a specific data type
|
Some C constructs require a way to designate a specific data type
|
||||||
independent of any particular variable or expression which has that
|
independent of any particular variable or expression which has that
|
||||||
type. The way to do this is with a @dfn{type designator}. The
|
type. The way to do this is with a @dfn{type designator}. The
|
||||||
constucts that need one include casts (@pxref{Explicit Type
|
constructs that need one include casts (@pxref{Explicit Type
|
||||||
Conversion}) and @code{sizeof} (@pxref{Type Size}).
|
Conversion}) and @code{sizeof} (@pxref{Type Size}).
|
||||||
|
|
||||||
We also use type designators to talk about the type of a value in C,
|
We also use type designators to talk about the type of a value in C,
|
||||||
|
|
Loading…
Reference in New Issue