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=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,d901a50a5adfec3c X-Google-Attributes: gid103376,public X-Google-Thread: 1094ba,9f0bf354542633fd X-Google-Attributes: gid1094ba,public X-Google-Thread: 1014db,3893224d5acbca8b X-Google-Attributes: gid1014db,public From: fred@genesis.demon.co.uk (Lawrence Kirby) Subject: Re: Fortran or Ada? Date: 1998/09/30 Message-ID: <907198459snz@genesis.demon.co.uk> X-Deja-AN: 396530671 References: X-Complaints-To: abuse@demon.net X-Mail2News-Path: news.demon.net!genesis.demon.co.uk X-Trace: mail2news.demon.co.uk 907203833 mail2news:26295 mail2news mail2news.demon.co.uk Organization: none Reply-To: fred@genesis.demon.co.uk Newsgroups: comp.lang.fortran,comp.lang.ada,comp.lang.c Date: 1998-09-30T00:00:00+00:00 List-Id: In article sokal@holyrood.ed.ac.uk "Daniel Barker" writes: >`In the language of everyday life it very often happens that the same word >signifies in two different ways - and therefore belongs to two different >symbols - or that two words, which signify in different ways, are >apparently applied in the same way in the proposition. OK. ... >`If a sign is NOT NECESSARY then it is meaningless. That is the meaning of >Occam's razor.' ... >If I may veer into another language, C - and thus justify adding another >news group to the `to' line - > >#include >main() >{ > int a[100]; /* `a' means array */ > printf("%p\n", a); /* `a' means pointer */ %p requires an argument of type void *. Make this printf("%p\n", (void *)a); > a = a + 1; /* ILLEGAL, since `a' means array again */ According to the wording of the standard the leftmost a here is converted to a pointer value that is the address of the first element of a. The reason this is an error is because this left hand operand is not a modifiable lvalue (in fact it isn't an lvalue at all, even though a initially is). >} > >`a' here means two different things: That is an unnecessarily complex interpretation (you mention Occam's razor above). In all cases here ``a'' refers to the array object defined at the top of the function. >(1) an array of 100 normal-width integers; >(2) a pointer to a normal-width integer (in fact, to the first integer in >an array of 100 such). Well, no. a always refers initially to the array. It is just that in some circumstances it is converted to a pointer to the first element of the array. The language works in a similar way in other circumstances e.g. short i=1, j = 2, k; k = i+j; In this case i and j are both converted to values of type int before the + operator is applied to theose values. However I hope you won't deny that i and j refer to variables of type short. >To say that, in the call to printf(), the first thing is implicitly >converted to the second thing is to linguistically `work around' the basic >problem, that `a' has two meanings. No, it how the standard describes the behaviour of the abstract machine that it defines. It is certainly possible to describe it in different terms with the same overall results but this is no more a `work around' than the alternatives. It is if anything the alternatives that are a workaround since they take a different approach to the actual definition. >Meaning (2) can also be expressed as &a[0] If you analyse this fully you get the following steps 1. a refers to the defined array object and is an lvalue 2. The expression causes this lvalue to be converted to a pointer to the first element of the array. 3. x[y] is equivalent to *(x + y) so a[0] is the same as *(a+0) which reduces to *a. Since this operand points to the first element of the array then the result of this is an lvalue which designates the first element of a. 4. Unary & takes the address of the object designated by its operand. Since the operand is the first element of the array the result is a pointer to the first element of the array. >So, the example reveals two faults in the C language. Namely, that `a', as >a local variable in one function, can have two meanings; No, a in main here always refers to the array object declared at the top of the function. It is an inherent property of C that context can cause the original value/lvalue to be converted to a value of a different type. This is best considered as a separate step. Not all contexts do this, The main ones that don't are &a and sizeof a. What this shows is that in different contexts different values can be derived from a. But that is true of any variable. The only difference here is that there is an implicit conversion from an array to a pointer which is more radical than most other implicit conversions. C supports another conversion which is IMO equally radical, if not more so: int *ptr = 0; converts the constant integral expression 0 to a null pointer of type int *. >and also that one >of these meanings is may be expressed by either of two symbols. This is a >crying shame! Why does `a' have two meanings, when, given the possibility >of `&a[0]', one would have sufficed without reducing the functionality of >the language? In many cases it is simpler and more natural to write a instead of &a[0], e.g. int *ptr; ptr = a; There is also ptr = a+1; where pointer arithmetic is performed on the pointer value derived from a. This sort of thing has been natural in C since the earliest days. If you say that it is the assignment or the addition operators that caused the conversion then you are back to a similar idea of context causing the conversion that the standard describes. >The answer is historical, as revealed by an interesting paper, "The >Development of the C Language" by Dennis Ritchie, available from Dennis >Ritchie's home page, http://plan9.bell-labs.com/cm/cs/who/dmr/index.html. Sure it does it because it allows you to express the construct more simply. One of C's defining features is pointer arithmetic (many other languages have pointers to allow linked datastructures and dynamic allocation but lack the ability to perform arithmetic directly on them). Pointer arithmetic is inherently performed over array objects so it is natural for C to have as simple a syntax as possible for converting from arrays to pointers. Consider puts("Hello, world"); In C string literals are arrays of char. If the language were changed as you suggest then this would have to be written as puts(&"Hello, world"[0]); (which incidentally is valid in C). Or how about char str[10]; strcpy(&str[0], &"A string"[0]); printf(&"The string is '%s'\n"[0], &str[0]); It would turn C into a much less readable language (even for people who thought it was unreadable to start with). -- ----------------------------------------- Lawrence Kirby | fred@genesis.demon.co.uk Wilts, England | 70734.126@compuserve.com -----------------------------------------