comp.lang.ada
 help / color / mirror / Atom feed
From: David Thompson <dave.thompson2@verizon.net>
Subject: Re: Legit Warnings or not
Date: Thu, 04 Aug 2011 01:56:51 -0400
Date: 2011-08-04T01:56:51-04:00	[thread overview]
Message-ID: <3qbk3752jm6etp8kjrmq75i8vksaq84oqf@4ax.com> (raw)
In-Reply-To: 98vi3lFinkU1@mid.individual.net

On Sat, 23 Jul 2011 12:20:53 +0300, Niklas Holsti
<niklas.holsti@tidorum.invalid> wrote:

> Randy Brukardt wrote:
> 
> > My point being that hidden pointers are extremely common in the 
> > implementation of modern programming languages, and certainly are common in 
> > Ada implementations. The only language I know of that insists on making such 
> > things explicit is C, and I think even it has some cases where the pointers 
> > are implicit (struct parameters).
> 
> Continuing that parenthesis: struct parameters in C are passed by value 
> unless you explicitly declare the parameters as pointers. I think the 

Yes. Or at least as-if; it would be legal for an ABI to actually pass
a pointer to a copy used only by the callee, or to a value which the
callee copies-in, but I've never seen anyone do so.

> only implicit introduction of "pointer" in C is when a function 
> parameter is declared as an array or a function, in which case the 
> formal parameter type is actually a pointer to the declared type. Other 
> rules let you omit the "address of" operator (&) on the actual parameters.
> 
Nearly.

If you declare a parameter as a function type F, it is actually a
pointer-to-F. An expression which is a function name is implicitly
converted to a pointer to that function, which is the correct type to
pass to a pointer-to-F parameter, and if you write &f it also creates
the same pointer. The function-call operation f(x) actually takes a
pointer-to-F as its left operand, which could either be a 'decayed'
actual function or a stored pointer including a parameter. Thus 
ptrf(x) calls the function ptrf points to; (*ptrf)(x) takes the target
of ptrf and re-forms a pointer and calls the same target; (**ptrf)(x)
takes the target, re-forms a pointer, derefences it, re-forms the
pointer again, and calls the same target, etc ad nauseam.

If you declare a parameter as an array type A with element E, it is
actually a pointer-to-E (not A). If an expression is an array lvalue
it is implicitly converted to a pointer to its first element, which is
the correct type to pass to pointer-to-E. Pointer-to-E doesn't 'know'
the array bound so void f (float x []) aka void f (float * x) can be
passed an array of float of any bound -- and the actual bound, or a
smaller used extent, must be passed or known by other means. 

The subscript operation a[i] effectively takes a pointer-to-E. 
Even more pedantic: subscripting in C is actually defined in terms of
pointer arithmetic: ptr +- integer yields a pointer moved up or down
by integer elements, usually integer*sizeof(element) bytes, and + is
commutative, and a[i] is _defined_ as *( (a) + (i) ), so actually i[a]
is equivalent to a[i], which was useful for early IOCCC entries.

But if you declare a parameter as pointer-to-array, that's a different
type that does know the bound (except if the bound is variable, 
a new feature in C99) and not passable or assignable from a
pointer-to-element. In that case you must explicitly write &array
(where array is the correct size) to get a suitable argument value.
Or write a cast, but that's uglier and often less robust.

Note that strings in C are just array of char(acter), or wchar_t,
containing a null terminator; thus the literal "xyz" in an expression
yields a pointer to char. (In C++ it's at least pointer to const char,
but in C 20 years of code existed before const was invented.)
This is actually just a case of the general array-element-pointer
rules above, but it is a very common case that has no syntactic
indication of an array and thus tends to confuse people.

What _is_ often done and might easily be confused is for struct
_returns_ from functions in C to be implemented using a pointer. 
Like all function return types, these are by-value in the abstract
semantics. But many C ABIs return primitive scalars (int, float, etc.)
in a register, which doesn't work for a (potentially) large struct. 
So it is common for the call sequence to provide temp space -- which
it can because C struct layout and size is fixed -- and pass a hidden
pointer which the callee epilogue uses to store the return value,
which the caller then uses. It is also possible, but more confusing,
to use a hybrid scheme where a struct type that is small enough to fit
in the desired register, typically 4 or 8 bytes, is returned there,
and only larger structs use caller-created space and pointer.
The issue doesn't arise for arrays because C can't return an array --
only a pointer used to access an array (in memory) or a struct
_containing_ an array (of static bound) in which case see above.




  reply	other threads:[~2011-08-04  5:56 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-07-20 22:30 Legit Warnings or not Anh Vo
2011-07-20 23:16 ` Robert A Duff
2011-07-21 18:43   ` Anh Vo
2011-07-23  0:26   ` Randy Brukardt
2011-07-23 14:26     ` Robert A Duff
2011-07-21  2:37 ` Jeffrey Carter
2011-07-21  9:50   ` Brian Drummond
2011-07-21 14:39     ` Dmitry A. Kazakov
2011-07-23  0:36       ` Randy Brukardt
2011-07-23  9:03         ` Dmitry A. Kazakov
2011-07-23 11:07           ` Simon Wright
2011-07-23 11:21             ` Dmitry A. Kazakov
2011-07-26 21:25           ` Randy Brukardt
2011-07-27  7:45             ` Dmitry A. Kazakov
2011-07-28  0:37               ` Randy Brukardt
2011-07-28  9:22                 ` Dmitry A. Kazakov
2011-07-28 14:22                   ` Robert A Duff
2011-07-28 14:41                     ` Dmitry A. Kazakov
2011-07-28 15:10                       ` Robert A Duff
2011-07-28 17:05                         ` Dmitry A. Kazakov
2011-07-28 23:32                           ` Randy Brukardt
2011-07-28 23:48                   ` Randy Brukardt
2011-07-29  6:57                     ` Simon Wright
2011-07-29 18:56                       ` Jeffrey Carter
2011-07-30  0:13                       ` Randy Brukardt
2011-07-29  7:41                     ` Dmitry A. Kazakov
2011-07-30  0:17                       ` Randy Brukardt
2011-07-30  8:27                         ` Dmitry A. Kazakov
2011-08-01 22:12                           ` Randy Brukardt
2011-08-02 10:01                             ` Dmitry A. Kazakov
2011-08-02 21:30                               ` Randy Brukardt
2011-08-03  9:01                                 ` Dmitry A. Kazakov
2011-08-03 20:35                                   ` Randy Brukardt
2011-08-04  8:11                                     ` Dmitry A. Kazakov
2011-08-05 23:57                                       ` Randy Brukardt
2011-08-06  8:23                                         ` Dmitry A. Kazakov
2011-08-08 21:30                                           ` Randy Brukardt
2011-07-23 14:32         ` Robert A Duff
2011-07-26 21:32           ` Randy Brukardt
2011-07-21 15:28     ` Adam Beneschan
2011-07-21 15:41       ` Robert A Duff
2011-07-21 20:12         ` Adam Beneschan
2011-07-23  0:31           ` Randy Brukardt
2011-07-21 17:40     ` Jeffrey Carter
2011-07-21 21:30       ` Brian Drummond
2011-07-21 21:54         ` Adam Beneschan
2011-07-22 10:16           ` Brian Drummond
2011-07-22 14:54             ` Adam Beneschan
2011-07-23  0:46             ` Randy Brukardt
2011-07-23  0:42         ` Randy Brukardt
2011-07-23  9:20           ` Niklas Holsti
2011-08-04  5:56             ` David Thompson [this message]
2011-07-23  9:24           ` Dmitry A. Kazakov
2011-07-23 12:36           ` Brian Drummond
2011-07-21 15:13   ` Robert A Duff
2011-07-23  0:52     ` Randy Brukardt
2011-07-23 14:48       ` Robert A Duff
2011-07-21 14:17 ` anon
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox