Liste des Groupes | Revenir à cl c |
On 09/07/2024 23:43, BGB wrote:These sorts of things may bleed through depending on implementation choices (and "optimizations"). Part of the compiler writing fun is trying to get good performance while also not breaking C semantics.On 7/9/2024 3:22 PM, James Kuyper wrote:ABI's are irrelevant to how the language is defined and how these expressions are evaluated. ABI's go along with details of the target - they can affect implementation-dependent behaviour but no more than that. (A clear example would be that alignment of fundamental types would normally be specified by an ABI.)On 7/9/24 14:55, BGB wrote:>
...The pass by reference, in this context, was referring to the ABI, not>
to C itself.
>
It looks from C's POV as-if it were by-value.
>
>
Which it is, depends on if one is looking at things at the language
level, ABI level, or IR level, ...
The C standard doesn't explicitly specify pass by value, or pass by
reference, or anything other passing mechanism. What it does say is what
a programmer needs to know to use the passing mechanism. It says that
the value of a function parameter that is seen by the code inside that
function is a copy of the value passed as an argument to the function.
The copy can be modified without changing the original. When a C
function's declaration looks as though it takes an array as an argument,
what that declaration actually means is that it takes a pointer value as
an argument, and it is a copy of that pointer's value which is seen
inside the function, and can be modified. The memory it points at is the
same as the memory pointed at by the corresponding argument.
>
>
>
We can probably agree that, in C:
typedef struct Foo_s Foo;
struct Foo_s {
int x, y, z, a, b, c;
};
>
int FooFunc(Foo obj)
{
obj.z = obj.x + obj.y;
return(obj.z);
}
>
int main()
{
Foo obj;
int z1;
obj.x=3;
obj.y=4;
obj.z=0;
z1=FooFunc(obj);
printf("%d %d\n", obj.z, z1);
}
>
Should print "0 7" regardless of how the structure is passed in the ABI.
>
So code that does not depend on implementation-dependent behaviour, such as your code here, will necessarily give the same results on all conforming C implementations.
Note that I did say: "C doesn't really allow for this".>It continues to astound me that people who claim to have written C compilers themselves - such as you and Bart - regularly show misunderstandings or ignorance about things that are clear in the C standards and which I would expect any experienced C programmer to know.
Though, one possibility being to relax the language such that both "0 7" and "7 7" are valid possibilities (the latter potentially allowing more performance by not needing to make a temporary local copy). Though, AFAIK, C doesn't really allow for this.
All arguments to function calls in C are passed by value. This is in 6.5.2.2p4 - it is a two sentence paragraph that you really ought to have read before even considering writing a C compiler.
Some languages do have pass by reference (or other types of parameter passing systems), and would give "7 7". C is not such a language. (And I have never heard of a language that would either result.)
Not all forms of "clever" are equal though...>A clever implementation would turn the whole of main() into a single puts("0 7") call.
An implementation could be clever though and only make local copies in cases where the structure is modified by the callee, as in the example above.
>
Compliers can generate whatever code they like, as long as the results are correct hin the end.
Les messages affichés proviennent d'usenet.