diff --git a/c.texi b/c.texi index 83e22a9..ccc2210 100644 --- a/c.texi +++ b/c.texi @@ -324,7 +324,7 @@ Pointers * Pointer Comparison:: Comparing memory address values. * Pointer Arithmetic:: Computing memory address values. * Pointers and Arrays:: Using pointer syntax instead of array syntax. -* Pointer Arithmetic Low Level:: More about computing memory address values. +* Low-Level Pointer Arithmetic:: More about computing memory address values. * Pointer Increment/Decrement:: Incrementing and decrementing pointers. * Pointer Arithmetic Drawbacks:: A common pointer bug to watch out for. * Pointer-Integer Conversion:: Converting pointer types to integer types. @@ -4845,12 +4845,17 @@ Names}. @chapter Pointers @cindex pointers -Among high-level languages, C is rather low level, close to the +Among high-level languages, C is rather low-level, close to the machine. This is mainly because it has explicit @dfn{pointers}. A pointer value is the numeric address of data in memory. The type of data to be found at that address is specified by the data type of the -pointer itself. The unary operator @samp{*} gets the data that a -pointer points to---this is called @dfn{dereferencing the pointer}. +pointer itself. Nothing in C can determine the ``correct'' data type +of data in memory; it can only blindly follow the data type of the +pointer you use to access the data. + +The unary operator @samp{*} gets the data that a pointer points +to---this is called @dfn{dereferencing the pointer}. Its value +always has the type that the pointer points to. C also allows pointers to functions, but since there are some differences in how they work, we treat them later. @xref{Function @@ -4868,7 +4873,7 @@ Pointers}. * Pointer Comparison:: Comparing memory address values. * Pointer Arithmetic:: Computing memory address values. * Pointers and Arrays:: Using pointer syntax instead of array syntax. -* Pointer Arithmetic Low Level:: More about computing memory address values. +* Low-Level Pointer Arithmetic:: More about computing memory address values. * Pointer Increment/Decrement:: Incrementing and decrementing pointers. * Pointer Arithmetic Drawbacks:: A common pointer bug to watch out for. * Pointer-Integer Conversion:: Converting pointer types to integer types. @@ -4960,9 +4965,11 @@ double *aptrd[5]; /* @r{Array of five pointers to @code{double}.} */ @end example @noindent -Because @samp{*} has higher syntactic precedence than subscripting, -you would subscript @code{aptrd} then dereference it. Therefore, it -declares an array of pointers, not a pointer. +Because @samp{*} has lower syntactic precedence than subscripting, +@samp{double *aptrd[5]} means, ``if you subscript @code{aptrd} by an +integer less than 5, then dereference it, you get a @code{double}.'' +Therefore, @code{*aptrd[5]} declares an array of pointers, not a +pointer to an array. @node Pointer Type Designators @section Pointer-Type Designators @@ -4979,10 +4986,12 @@ double (*)[5] /* @r{Pointer to @code{double[5]}.} */ @end example Remember, to understand what type a designator stands for, imagine the -variable name that would be in the declaration, and figure out what -type it would declare that variable with. @code{double (*)[5]} can -only come from @code{double (*@var{variable})[5]}, so it's a pointer +corresponding variable declaration with a variable name in it, and +figure out what type that variable would have. Thus, the type +designator @code{double (*)[5]} corresponds to the variable declaration +@code{double (*@var{variable})[5]}. That deciares a pointer variable which, when dereferenced, gives an array of 5 @code{double}s. +So the type designator means, ``pointer to an array of 5 @code{double}s.'' @node Pointer Dereference @section Dereferencing Pointers @@ -5232,10 +5241,10 @@ If one of the operands is @code{void *} (@pxref{Void Pointers}) and the other is another pointer type, the comparison operator converts the @code{void *} pointer to the other type so as to compare them. (In standard C, this is not allowed if the other type is a function -pointer type, but that works in GNU C@.) +pointer type, but it works in GNU C@.) Comparison operators also allow comparing the integer 0 with a pointer -value. Thus works by converting 0 to a null pointer of the same type +value. This works by converting 0 to a null pointer of the same type as the other operand. @node Pointer Arithmetic @@ -5331,10 +5340,10 @@ subtract_pointers () @} @end example -The addition operation does not know where arrays are. All it does is -add the integer (multiplied by object size) to the value of the -pointer. When the initial pointer and the result point into a single -array, the result is well-defined. +The addition operation does not know where arrays begin or end in +memory. All it does is add the integer (multiplied by target object +size) to the numeric value of the pointer. When the initial pointer +and the result point into the same array, the result is well-defined. @strong{Warning:} Only experts should do pointer arithmetic involving pointers into different memory objects. @@ -5344,15 +5353,18 @@ The difference between two pointers has type @code{int}, or declare it is to use the typedef name @code{ptrdiff_t} defined in the file @file{stddef.h}. -This definition of pointer subtraction is consistent with -pointer-integer addition, in that @code{(p3 - p1) + p1} equals -@code{p3}, as in ordinary algebra. +C defines pointer subtraction to be consistent with pointer-integer +addition, so that @code{(p3 - p1) + p1} equals @code{p3}, as in +ordinary algebra. Pointer subtraction works by subtracting +@code{p1}'s numeric value from @code{p3}'s, and dividing by target +object size. The two pointer arguments should point into the same +array. In standard C, addition and subtraction are not allowed on @code{void *}, since the target type's size is not defined in that case. Likewise, they are not allowed on pointers to function types. However, these operations work in GNU C, and the ``size of the target -type'' is taken as 1. +type'' is taken as 1 byte. @node Pointers and Arrays @section Pointers and Arrays @@ -5374,26 +5386,26 @@ symmetrically, so one must be a pointer and the other an integer; it does not matter which comes first. Since indexing with square brackets is defined in terms of addition -and dereference, that too is symmetrical. Thus, you can write +and dereferencing, that too is symmetrical. Thus, you can write @code{3[array]} and it is equivalent to @code{array[3]}. However, it would be foolish to write @code{3[array]}, since it has no advantage and could confuse people who read the code. It may seem like a discrepancy that the definition @code{*(@var{a} + -@var{b})} requires a pointer, but @code{array[3]} uses an array value +@var{b})} requires a pointer, while @code{array[3]} uses an array value instead. Why is this valid? The name of the array, when used by itself as an expression (other than in @code{sizeof}), stands for a -pointer to the arrays's zeroth element. Thus, @code{array + 3} +pointer to the array's zeroth element. Thus, @code{array + 3} converts @code{array} implicitly to @code{&array[0]}, and the result is a pointer to element 3, equivalent to @code{&array[3]}. -Since square brackets are defined in terms of such addition, +Since square brackets are defined in terms of such an addition, @code{array[3]} first converts @code{array} to a pointer. That's why it works to use an array directly in that construct. -@node Pointer Arithmetic Low Level -@section Pointer Arithmetic at Low Level -@cindex pointer arithmetic, low level +@node Low-Level Pointer Arithmetic +@section Pointer Arithmetic at Low-Level +@cindex pointer arithmetic, low-level @cindex low level pointer arithmetic The behavior of pointer arithmetic is theoretically defined only when @@ -5407,7 +5419,8 @@ address, which is in fact an integer---call it @var{pint}. It treats @var{i} as a number of elements of the type that @var{p} points to. These elements' sizes add up to @code{@var{i} * sizeof (*@var{p})}. So the sum, as an integer, is @code{@var{pint} + @var{i} * sizeof -(*@var{p})}. This value is reinterpreted as a pointer like @var{p}. +(*@var{p})}. This value is reinterpreted as a pointer of the same +type as @var{p}. If the starting pointer value @var{p} and the result do not point at parts of the same object, the operation is not officially legitimate, @@ -5448,7 +5461,8 @@ long} would always work, but it is cleaner to use @code{intptr_t}.) The @samp{++} operator adds 1 to a variable. We have seen it for integers (@pxref{Increment/Decrement}), but it works for pointers too. For instance, suppose we have a series of positive integers, -terminated by a zero, and we want to add them all up. +terminated by a zero, and we want to add them up. Here is a simple +way to step forward through the array by advancing a pointer. @example int @@ -5481,12 +5495,12 @@ takes precedence over a prefix operator. Therefore, it dereferences @code{p}, and increments @code{p} afterwards. Incrementing a variable means adding 1 to it, as in @code{p = p + 1}. Since @code{p} is a pointer, adding 1 to it advances it by the width of the datum it -points to---in this case, one @code{int}. Therefore, each iteration +points to---in this case, @code{sizeof (int)}. Therefore, each iteration of the loop picks up the next integer from the series and puts it into @code{next}. This @code{for}-loop has no initialization expression since @code{p} -and @code{sum} are already initialized, it has no end-test since the +and @code{sum} are already initialized, has no end-test since the @samp{break;} statement will exit it, and needs no expression to advance it since that's done within the loop by incrementing @code{p} and @code{sum}. Thus, those three expressions after @code{for} are @@ -5522,11 +5536,11 @@ and add it to @code{p}. (Recall that @code{p[i]} means @code{*(p + i)}.) Either way, it uses the same address to get the next integer. It makes no difference in this program whether we write @code{i++} or -@code{++i}, because the value is not used. All that matters is the -effect, to increment @code{i}. +@code{++i}, because the value @emph{of that expression} is not used. +We use it for its effect, to increment @code{i}. The @samp{--} operator also works on pointers; it can be used -to scan backwards through an array, like this: +to step backwards through an array, like this: @example int @@ -5561,10 +5575,10 @@ memory. However, if you unintentionally adjust a pointer across the bounds of the object and into some other object, the system has no way to detect this error. -A bug which does that can easily result in clobbering part of another -object. For example, with @code{array[-1]} you can read or write the -nonexistent element before the beginning of an array---probably part -of some other data. +A bug which does that can easily result in clobbering (overwriting) +part of another object. For example, with @code{array[-1]} you can +read or write the nonexistent element before the beginning of an +array---probably part of some other data. Combining pointer arithmetic with casts between pointer types, you can create a pointer that fails to be properly aligned for its type. For