Liste des Groupes | Revenir à cl c |
On 09/07/2024 15:31, David Brown wrote: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.On 08/07/2024 19:39, BGB wrote:Arrays are passed by reference: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.
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].
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.So if you have these structs and declarations :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.
>
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 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.
(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.
Les messages affichés proviennent d'usenet.