Warning: mysqli::__construct(): (HY000/1203): User howardkn already has more than 'max_user_connections' active connections in D:\Inetpub\vhosts\howardknight.net\al.howardknight.net\includes\artfuncs.php on line 21
Failed to connect to MySQL: (1203) User howardkn already has more than 'max_user_connections' active connectionsPath: ...!2.eu.feeder.erje.net!feeder.erje.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: David Brown 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 16:31:30 +0200 Organization: A noiseless patient Spider Lines: 97 Message-ID: References: <871q48w98e.fsf@nosuchdomain.example.com> <87wmlzvfqp.fsf@nosuchdomain.example.com> <87h6d2uox5.fsf@nosuchdomain.example.com> <20240707164747.258@kylheku.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Date: Tue, 09 Jul 2024 16:31:31 +0200 (CEST) Injection-Info: dont-email.me; posting-host="b5f81ffa340fccea092912f722a4136c"; logging-data="1502630"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/HMr+R/8SZvgUmgZzig9dWMdNGxEziIdo=" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0 Cancel-Lock: sha1:QnTxb6UJfvuqu0xsN0t/HXg9GH4= Content-Language: en-GB In-Reply-To: Bytes: 5356 On 08/07/2024 19:39, BGB wrote: > On 7/7/2024 11:28 PM, James Kuyper wrote: >> On 7/7/24 20:02, Kaz Kylheku wrote: >> ... > >> I see no point in having implicit pointers, but I don't believe that >> they are prohibited. >> > > They mostly exist in a "sort of simpler to implement the compiler this > way" sense. > > In the implicit pointer case, the compiler just treats it as-if it were > an explicit pointer. In this case, both are basically treated as being > roughly equivalent at the IR levels. > > And, most of the code-generation stage doesn't need separate handling > for arrays and pointers, but can use combined "ArrayOrPointer" handling > or similar. > > It had all seemed "obvious enough". > > > > > Similar reasoning for passing structs by-reference in the ABI: >   Pass by reference is easy to implement; >   In place copying and decomposing into registers, kinda bad. > > 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. Even when you use pointer arguments or return types, you are passing or returning pointer values. C programmers use pointers to get the effect of passing by reference, but in C you use pointers to be explicit about references. Structs in C are passed by value, and returned by value. Not by reference. The C standards don't say how passing structs around by value is to be implemented - that is hidden from the programmer. Usually ABI's (which are also hidden from the programmer) specify the implementation details, but some ABI's are weak in that area. Generally, structs up to a certain size or complexity are passed in registers while bigger or more advanced types are passed via addresses (pointing to stack areas) in registers or the stack, just like any other bigger types. This is not "pass by reference" as far as the C programming is concerned - but you could well call it that at the assembly level. Where the line between "passing in registers" and "passing via addresses to space on the stack" is drawn, is entirely up to the compiler implementation and any ABI requirements. Some simpler compilers will pass all structs via addresses, no matter how simple they are, while others will aim to use registers whenever possible. 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); This is not, as you wrote somewhere, something peculiar to MSVC - it is the technique used by virtually every C compiler, except perhaps for outdated brain-dead 8-bit microcontrollers that have difficulty handling data on a stack. And it is not really "pass by reference" or "implicit pointers", it is just passing addresses around behind the scenes in the implementation.