From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: a07f3367d7,5d4ade2fd8fd67c6 X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news3.google.com!feeder.news-service.com!eternal-september.org!feeder.eternal-september.org!.POSTED!not-for-mail From: David Thompson Newsgroups: comp.lang.ada Subject: Re: Legit Warnings or not Date: Thu, 04 Aug 2011 01:56:51 -0400 Organization: Poor Message-ID: <3qbk3752jm6etp8kjrmq75i8vksaq84oqf@4ax.com> References: <531193e0-3305-4292-9ed8-0176226c1d00@x12g2000yql.googlegroups.com> <98vi3lFinkU1@mid.individual.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Injection-Info: mx04.eternal-september.org; posting-host="6ZEQgAYNQVVsakf+oSakQw"; logging-data="8785"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18pjOBj2D0Tit2xiV9wazobpaeLbgyhBtQ=" X-Newsreader: Forte Agent 3.3/32.846 Cancel-Lock: sha1:guC2hgNl2Zl6Aal5TrYUiSaAj9Q= Xref: g2news1.google.com comp.lang.ada:20458 Date: 2011-08-04T01:56:51-04:00 List-Id: On Sat, 23 Jul 2011 12:20:53 +0300, Niklas Holsti 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.