Path: csiph.com!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson 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 13:47:21 -0700 Organization: None to speak of Lines: 107 Message-ID: <87le29ug86.fsf@nosuchdomain.example.com> References: <87h6d2uox5.fsf@nosuchdomain.example.com> <20240707164747.258@kylheku.com> <877cdur1z9.fsf@bsb.me.uk> <871q42qy33.fsf@bsb.me.uk> <87ed82p28y.fsf@bsb.me.uk> <87r0c1nzjj.fsf@bsb.me.uk> MIME-Version: 1.0 Content-Type: text/plain Injection-Date: Wed, 10 Jul 2024 22:47:22 +0200 (CEST) Injection-Info: dont-email.me; posting-host="2ff96a67704e58776cf4f9c1dffac965"; logging-data="2150127"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+oA0Fvc5MGgLORgW1wosQb" User-Agent: Gnus/5.13 (Gnus v5.13) Cancel-Lock: sha1:SIMIKVgYhYIOoy/uMje4kbg9QEg= sha1:kA4vp/y2viZlTgdw54WAjlvK8R0= Xref: csiph.com comp.lang.c:387017 bart 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 > 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 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. > In C you get that behaviour anyway (possibly to the surprise of many), > in a language which only has pass-by-value, and without needing > explicit pointers. Yes. > That really is remarkable. And not unsafe at all! Yes, it's remarkable. Yes, it can be unsafe. It's particularly unsafe for someone who doesn't understand it, perhaps because they took your advice. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com void Void(void) { Void(); } /* The recursive call of the void */