| Deutsch English Français Italiano |
|
<v6jolf$1ebr7$2@dont-email.me> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!news.mixmin.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: David Brown <david.brown@hesbynett.no>
Newsgroups: comp.lang.c
Subject: =?UTF-8?Q?Re=3a_technology_discussion_=e2=86=92_does_the_world_need?=
=?UTF-8?B?IGEgIm5ldyIgQyA/?=
Date: Tue, 9 Jul 2024 18:31:43 +0200
Organization: A noiseless patient Spider
Lines: 92
Message-ID: <v6jolf$1ebr7$2@dont-email.me>
References: <v66eci$2qeee$1@dont-email.me> <v67gt1$2vq6a$2@dont-email.me>
<v687h2$36i6p$1@dont-email.me> <871q48w98e.fsf@nosuchdomain.example.com>
<v68dsm$37sg2$1@dont-email.me> <87wmlzvfqp.fsf@nosuchdomain.example.com>
<v6ard1$3ngh6$4@dont-email.me> <v6b0jv$3nnt6$1@dont-email.me>
<87h6d2uox5.fsf@nosuchdomain.example.com> <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>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Tue, 09 Jul 2024 18:31:43 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="b5f81ffa340fccea092912f722a4136c";
logging-data="1519463"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+h8/eNP/ockGnhGSTu1XEyiDVXUuOCME0="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101
Thunderbird/102.11.0
Cancel-Lock: sha1:xzaCbs0aVADvvQraH9f1SF/q+EQ=
Content-Language: en-GB
In-Reply-To: <v6jiud$1dsjb$1@dont-email.me>
Bytes: 5115
On 09/07/2024 16:54, bart wrote:
> On 09/07/2024 15:31, David Brown wrote:
>> On 08/07/2024 19:39, BGB wrote:
>
>>> Though, this one seems to be a common point of divergence between
>>> "SysV" and "Microsoft" ABIs. Sometimes a target will have an ABI
>>> defined, and the MS version was almost the same, just typically
>>> differing in that it passes structs by reference and provides a spill
>>> space for register arguments.
>>>
>>
>> I don't think it is helpful that you keep mixing /logical/ terms with
>> /implementation/ terms.
>>
>> In C, there is no "pass by reference" or "return by reference". It is
>> all done by value.
>
> Arrays are passed by reference:
>
> void F(int a[20]) {}
>
> int main(void) {
> int x[20];
> F(x);
> }
>
> Although the type of 'a' inside 'F' will be int* rather than int(*)[20].
Arrays are not passed by reference in C. When you use the array in most
expression contexts, including as an argument to a function call, the
array expression is converted to a pointer to its first element, and
that pointer is passed by value.
That's why the array type information is lost in the call, and you get a
pointer in the function - /not/ a reference to an array.
>
>> So if you have these structs and declarations :
>>
>> struct small { uint16_t a; uint16_t b; };
>> struct big { uint32_t xs[10]; };
>>
>> struct small foos(struct small y);
>> struct big foob(struct big y);
>>
>> Then compilers will typically implement "x = foos(y)" as though it were:
>>
>> extern uint32_t foos(uint32_t ab);
>> uint32_t _1 = foos(y.a << 16) | (y.b);
>> struct small x = { _1 >> 16, _1 & 0xffff };
>>
>> And they will typically implement "x = foosb(y)" as though it were:
>>
>> extern void foob(struct big * ret, const struct big * xs);
>> struct big x;
>> foob(&x, &y);
>
> From what I've seen, structs that are not small enough to be passed in
> registers, are copied to a temporary, and the address of that temporary
> is passed.
That will depend on the details of the compiler, optimisation, and what
happens to the array after the call. But yes, that is certainly
something that is done.
>
> This seems to be the case even when the struct param is marked 'const'.
"const" in C is not strong enough to guarantee that things will not be
changed in this context. If you have a pointer to non-const data,
convert it to a pointer to const, and then later convert it back to a
pointer to non-const, you can use that to change the data. Thus using a
pointer to const does not let the compiler be sure that the data cannot
be changed by the function - so if the struct/array is used again later,
and its value must be preserved, the compiler needs to make a copy.
(I'd like it if there were a way to have such guarantees, but C is what
C is.)
>
> (My compiler won't create a copy when the parameter is 'const'. I
> assumed that was how gcc did it; I was wrong.)
Your compiler is wrong. But if you only give it code where the const
pointer is never converted to a non-const pointer, you'll be safe.
>
> This is for Win64 ABI, however an ABI will only say they are passed by
> reference; it will not stipulate making a copy. That is up to the
> language implementation.
>