Deutsch   English   Français   Italiano  
<vtdk1f$e52f$1@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail
From: bart <bc@freeuk.com>
Newsgroups: comp.lang.c
Subject: Re: do { quit; } else { }
Date: Sat, 12 Apr 2025 12:50:07 +0100
Organization: A noiseless patient Spider
Lines: 121
Message-ID: <vtdk1f$e52f$1@dont-email.me>
References: <vspbjh$8dvd$1@dont-email.me> <vt3iqh$2ka99$1@dont-email.me>
 <vt5fed$ccri$1@dont-email.me> <vt5js2$g1t7$1@dont-email.me>
 <20250409142303.00004645@yahoo.com> <87ikndqabc.fsf@nosuchdomain.example.com>
 <20250410115501.000037a5@yahoo.com> <vt8ei8$2vn84$1@dont-email.me>
 <20250410080629.532@kylheku.com> <vt94q5$3jjod$1@dont-email.me>
 <vt9628$3hhr8$3@dont-email.me> <vtammh$174ev$1@dont-email.me>
 <vtavn9$1dp7m$3@dont-email.me> <vtb8nv$1plb2$2@dont-email.me>
 <vtba81$1qfbm$1@dont-email.me> <vtbc6o$1te2o$1@dont-email.me>
 <vtbhjv$24api$1@dont-email.me> <vtbn2k$293r1$1@dont-email.me>
 <vtc19j$2kqlj$1@dont-email.me> <87a58mqt2o.fsf@nosuchdomain.example.com>
 <vtc7mp$2q5hr$1@dont-email.me> <875xjaqmgf.fsf@nosuchdomain.example.com>
 <vtcfhp$325g6$1@dont-email.me> <20250411192435.573@kylheku.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Sat, 12 Apr 2025 13:50:07 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="5b5cdf67fe25ae40eb3e543c34a3e4c8";
	logging-data="463951"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX19xJD0RXH/OZXguL2jQCObs"
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:+p7V1SNzyK7P08dcLEOJFpfNRdE=
In-Reply-To: <20250411192435.573@kylheku.com>
Content-Language: en-GB
Bytes: 6046

On 12/04/2025 03:43, Kaz Kylheku wrote:
> On 2025-04-12, bart <bc@freeuk.com> wrote:

>> C type syntax is famous for being difficult and confusing; I think most
>> will agree about that. Even the creators said so.
> 
> If you had a function that takes an int, that returned a pointer to an
> array, how would you pass in 42, and then get at the third element?
> 
>     f(42)        // gets the pointer to the array
> 
>     (*f(42))     // designates the array
> 
>     (*f(42))[2]  // gets at the third element.
> 
> Ok, now declaring a function of int, which returns a pointer to an array
> of 16 elements:
> 
>     (*f(int))[16];
> 
> Notice any resemblance? The 42 argumet has changed to a type specifier
> for the corresponding parameter type. The array reference turns into
> the size. Minor!

> We need a type specifier to the elements:
> 
>     double (*f(int))[16];
> 
> Declaration follows use: it's not just a slogan, it's real!

I'm sorry, but it doesn't work! The thought processes are entirely 
different between writing expressions, and declaring types. They differ 
in many ways anyway:

* A typespec needs a base type; an expr doesn't
* A typespec needs to express the whole thing right up to the base type; 
an expr can be partial
* A typespec can include 'const' and other attributes; an expr doesn't
* A typespec uses '*' for pointers, an expr can use '*' or '[]' to deref
* A typespec uses '[]' for arrays; an expression can choose to use '*' 
to index
* A typespec uses (*) for function pointers, but an expression can 
choose to omit both that * and the accompanying ().

Further if you have an expression like (*A)[i] + (*B[i]) + (*C[i]), then 
you necessarily have to elaborate each term, but it shouldn't be 
necessary to repeat that typespec for each in the declarations.

C doesn't directly have the means to centralise a common type, you have 
to do:

    typedef int (*Arr)[10];
    Arr A, B, C;

or:
    typeof(int (*)[10]) A, B, C

Here there is a clear (and clean!) disconnect between each variable, and 
its type. A variable's type shouldn't be something it has to 'wear' 
wrapped around it, so that it literally looks like an expression. That 
would be a bizarre concept.

But unfortunately people are used to thinking that this is normal:

     int (*A)[10], (*B[10]), (*C)[10];

Even if you wrote this, perhaps you are passing those pointers to a 
function:

    F(A, B, C)

Hmm, those terms don't look much like their declarations, do they?!


> If you don't like the declaration syntax, it's possibly because
> you don't like the expression syntax for working with pointer
> dereferencing and arrays, which it mirrors. (You not liking
> C expression syntax: billion to one odds, right?)

Yes, making deref a prefix op was a bad idea. Postfix is much better 
(but the choice of '*' makes that problematical).

My examples become (ignoring the unsuitability of '*'):

    int A*[10], B*[10], C*[10];
    A*[i] + B*[i] + C*[i]

Generally cleaner syntax all round. Maybe people would now use proper 
pointer-to-array types (T(*)[] in current syntax) instead of the less 
safe T*.

The -> operator can be dispensed with too: you write P*.m or Q**.m 
instead of the messy (*P).m or P->m or (*Q)->m.

> IDEA: maybe you would like the "dedclaration follows use", if it was
> rendered over a different expression grammar in which pointer, arrays
> and whatnot work the way you like. If didn't dislike the "use",
> you might not dislike "declaration follows use".
> 
> Now, from this "envelope shape":
> 
>     double (.......)[16];
> 
> we know that whatever ..... is, it is an array of 16 doubles.
> This .... is called a "type hole" by functional programmers working
> in Haskell and whatnot.
> 
> If we replace the hole with a name like abc:
> 
>     double (abc)[16];
> 
> then what is being declared is that name.  We get an object abc which is
> such an array. The parentheses are then unnecessary and we can drop
> them.
> 
> If we plug in   *f(int)  instead of abc, then  *f(int)  isn't what is
> being declared: f is. But we know that when this f is called, and the

I'm lost, sorry. Things are getting more complicated, not simpler!