Deutsch   English   Français   Italiano  
<875xtcvomx.fsf@nosuchdomain.example.com>

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

Path: ...!weretis.net!feeder8.news.weretis.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Keith Thompson <Keith.S.Thompson+u@gmail.com>
Newsgroups: comp.lang.c
Subject: Re: technology discussion =?utf-8?Q?=E2=86=92?= does the world need
 a "new" C ?
Date: Wed, 10 Jul 2024 16:00:22 -0700
Organization: None to speak of
Lines: 144
Message-ID: <875xtcvomx.fsf@nosuchdomain.example.com>
References: <v66eci$2qeee$1@dont-email.me> <v6d779$6rk5$2@dont-email.me>
	<v6e76u$c0i9$1@dont-email.me> <v6esqm$fian$2@dont-email.me>
	<v6f7vg$hgam$1@dont-email.me> <20240707164747.258@kylheku.com>
	<v6gl83$s72a$1@dont-email.me> <v6h8ao$ur1v$1@dont-email.me>
	<v6jhk3$1drd6$1@dont-email.me> <v6jiud$1dsjb$1@dont-email.me>
	<877cdur1z9.fsf@bsb.me.uk> <v6joi4$1epoj$1@dont-email.me>
	<871q42qy33.fsf@bsb.me.uk> <v6k6i0$1h4d3$1@dont-email.me>
	<87ed82p28y.fsf@bsb.me.uk> <v6m03l$1tf05$1@dont-email.me>
	<87r0c1nzjj.fsf@bsb.me.uk> <v6m7ae$1v125$1@dont-email.me>
	<v6ma1d$1vfv2$1@dont-email.me>
	<87le29ug86.fsf@nosuchdomain.example.com>
	<v6mv42$22r1f$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Date: Thu, 11 Jul 2024 01:00:26 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="c51c7f9518f437252e8df6d7af482dc8";
	logging-data="2224570"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX189yxRnLcqktjZrMyWBJlgX"
User-Agent: Gnus/5.13 (Gnus v5.13)
Cancel-Lock: sha1:Ma+l4qGhK0z25anE8sh5v8azoRk=
	sha1:Lj31FipEp1vrtAOeC1X+thxisZo=
Bytes: 6782

bart <bc@freeuk.com> writes:
> On 10/07/2024 21:47, Keith Thompson wrote:
>> bart <bc@freeuk.com> writes:
>>> On 10/07/2024 15:54, Janis Papanagnou wrote:
>>>> Values passed (including values of pointers [used for arrays]) are
>>>> handled (in the functions) as copies and cannot change the original
>>>> entities (values or dereferenced objects) in the calling environment.
>>>> To make it possible to change entities in the calling environment
>>>> in "C" you have to implement the necessary indirection by pointers.
>>>
>>>
>>> You don't have to do anything at all:
>>>
>>>    #include <stdio.h>
>>>    typedef unsigned char byte;
>>>    typedef byte vector[4];
>>>
>>>    void F(vector a) {
>>>        a[0]+=3;
>>>        a[1]+=3;
>>>    }
>>>
>>>    int main(void) {
>>>        vector v = {10,20,30,40};
>>>
>>>        printf("%d %d %d %d\n", v[0], v[1], v[2], v[3]);  // 10 20 30 40
>>>        F(v);
>>>        printf("%d %d %d %d\n", v[0], v[1], v[2], v[3]);  // 13 23 30 49
>>>    }
>>>
>>> Here it looks superficially as though 'v' is passed by value (and it
>>> is of a size that the ABI /would/ pass by value), yet F changes its
>>> caller's data, perhaps unintentionally.
>> Here's a modified version of your program:
>> ```
>> #include <stdio.h>
>> typedef unsigned char byte;
>> typedef byte vector[4];
>> void F(vector a) {
>>      a[0]+=3;
>>      a[1]+=3;
>>      printf("In F\n");
>>      printf("    a is of type %s\n",
>>             _Generic(a, vector: "vector", byte*: "byte*"));
>>      printf("    a        = %p\n", (void*)a);
>>      printf("    a+1      = %p\n", (void*)(a+1));
>>      printf("    sizeof a = %zu\n", sizeof a);
>>      printf("    *a       = %d\n", *a);
>> }
>> int main(void) {
>>      vector v = {10,20,30,40};
>>      printf("%d %d %d %d\n", v[0], v[1], v[2], v[3]);  // 10 20 30
>> 40
>>      F(v);
>>      printf("%d %d %d %d\n", v[0], v[1], v[2], v[3]);  // 13 23 30 49
>> }
>> ```
>> The output is:
>> ```
>> 10 20 30 40
>> In F
>>      a is of type byte*
>>      a        = 0x7ffdf0158d44
>>      a+1      = 0x7ffdf0158d45
>>      sizeof a = 8
>>      *a       = 13
>> 13 23 30 40
>> ```
>> (The pointer values will vary.)
>> 
>>>> Your insistence is amazing.
>>> /I/ am amazed at everyone's insistence that there is nothing
>>> remarkable about this, and that it is nothing at all like
>>> pass-by-reference.
>>>
>>> So, how do I write F in C so that the caller's data is unchanged?
>> Make a copy of the array data if you need to change a local copy, or
>> define it as const so the function can't change it, or wrap the array in
>> a struct.
>> 
>>> Sure, true pass-by-reference has some extra properties, but if I
>>> wanted to duplicate the behaviour of the above in my language, I have
>>> to use pass-by-reference.
>> So your language has pass-by-reference.  Great.  I'm sure we're all
>> very
>> happy for you.
>
> Apparently so has C! At least, there is enough of a mish-mash between
> by-value, by-reference, and explicit pointers, that it provides most
> of the benefits that true by-reference gives.

No, C does not have by-reference argument passing.

bart, do you understand that the code I added to your example
demonstrates that the parameter `a` is of pointer type, not array type?
Did you understand that before I posted that code?

> What the effective passing mode is, is unknown.

Not to anyone who's paying attention.  The effective passing mode is
by-value.

>                                                 But I think ascribing
> the behaviour of your program above as due to 'pass by value' is
> misleading. The 'value' of what?

In your example, it's the value of the address of the initial element of
the array object v.

But you understand that already, don't you?

> 'pass by reference' doesn't quite cover it, but it's a closer match to
> that behaviour.

Pretending that the array is being passed by reference is a closer match
than pretending that the array is being passed by value, but both are
wrong.

The truth, ONE MORE TIME, is that the array is not passed at all, but
the address of its 0th element is passed BY VALUE.

We can emulate pass-by-reference in C using pointers, and some C
features make it "easy" to do so implicitly.  C does not have
pass-by-reference as language feature, any more than it has linked lists
as a language feature.  Both can be emulated using pointers.

[...]

> Which is more unsafe out these:
>
> * Someone thinks that that 'v' parameter is passed by-value (because
>   everything in C is), and the caller's data is therefore safe. No
>   need to use 'const' either.
>
> * Someone thinks, even eroneously, that the 'v' parameter is passed by
>   reference, so theyt take care not to directly modify it, or they
>   will think about using 'const'.

Both are wrong, and both are unsafe.  Knowing how C is really defined
has at least the potential for safety.  But you know that.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */