Path: csiph.com!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: usecases of void foo(char **b) {} Date: Tue, 01 Nov 2016 11:46:46 -0700 Organization: None to speak of Lines: 103 Message-ID: References: <5a9aae7f-eb86-4c7b-bc93-142504b1d0a9@googlegroups.com> <49899127-bf04-4a84-a374-5bebfbe7f4f7@googlegroups.com> <8f154274-4b6f-41f3-8489-c94f98e5c559@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: mx02.eternal-september.org; posting-host="3c9491fcd50349ea336243ee8772beaa"; logging-data="28834"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+RHapclAUqjsB7t205jEcv" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:oydjNvpCdcpC7+LmPM4v7GSCjl0= sha1:0zTo8l3h82ZJSO/AmbEyiZgWY6A= Xref: csiph.com comp.lang.c:95535 BartC writes: > On 01/11/2016 16:02, John Bode wrote: > >> The hardware does not define the language. > > Up to a point it does. It can't be a coincidence that a language like C > can be implemented reasonably efficiently on a range of hardware. Hardware clearly *influences* the design of the language. But once that design is written down as a standard, implementations do whatever they need to do to implement the written semantics on whatever target hardware is being used. If that means emulating binary on trinary hardware, that's what you need to do to have a conforming implementation. (Admittedly that's unlikely to be necessary in real life; there have been trinary computers, but I doubt that there's ever been a conforming C implementation for them.) > And independently of the hardware, given these declarations: > > enum {A}; > int B; > int *C; > int **D: > > then you can probably make the following inferences about what happens > in the evaluation of each of these lines, without knowing what hardware > they will run on: Assuming everytiing is initialized properly: > A; // no dereference (immediate load) In terms of C semantics, it evaluates and discards the value 0, of type int. Almost certainly no code is generated. > B; // one implicit deref (equating to *&B) That evaluates and discards the value of the int object B. Again, any decent compiler will generate no code. There is no dereference, which is an operation applied to a pointer value. (Actually the standard doesn't use the word "dereference" except in passing in one non-normative footnote.) > *C; // one explicit deref > **D; // two explicit derefs Yes (but again, it's likely no code will be generated). But by your logic, surely the first would have one implicit dereference to obtain the value of C, and an explicit dereference to obtain the value of *C. You're using the word "dereference" in two *very* different ways. One is the way most of us use it, to determine the value of the object that a pointer value points to. The other is to determine the value of a named object, something that the standard calls "lvalue conversion" (N1570 6.3.2.1). Even if code is generated, it's entirely possible that any or all of A, B, C, or D are stored in registers, or that the compiler is able to determine their values without re-fetching them. The C semantics of the above statements is quite clear. The generated code from a given compiler is likely to be clear as well to someone who understands the target machine. Mixing them together as you do is not helpful. As you commonly do, you're rejecting the standard terminology most of us use and describing things in terms that create more confusion than necessary. [...] > What happens here then: > > int B[10]; > int (*Q)[10] = &B; > > Q is a pointer. *Q yields one object, true, but that object is an entire > array, that can then be indexed: > > (*Q)[i]; Is that a serious question? Come on, you know this stuff; you just don't like it. A pointer points to a single object (and, via pointer arithmetic, may also be used to access other objects that are elements of the same array object). An object can be of any object type -- including an array type. If the pointed-to object happens to be an array object, then of course it can be indexed -- because it's an array object. There's nothing magical about pointers to array types. They work exactly as you'd expect once you understand how pointers and arrays work. I expect you'll reply to this with yet another complaint that arrays and pointers are confusing. I agree, they certainly can be. Stop making it worse. -- Keith Thompson (The_Other_Keith) kst-u@mib.org Working, but not speaking, for JetHead Development, Inc. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister"