5 ms·
This isn't correct. The compiler would not have to produce a copy in either case. The call to bar() can not change the value of l because the person who calle
by Negitivefrags 5y ago
This isn't correct.
The compiler would not have to produce a copy in either case.
The call to bar() can not change the value of l because the person who called foo1 gave you an immutable pointer to it.
How did foo1's caller know it was immutable?
If the value passed to foo1 was a local variable, or one of it's arguments passed to it by immutable pointer, then all the compiler has to do is check if, in that function, it created a mutable pointer to the value and put it somewhere accessable to someone else. If it did not, then it can just pass the pointer right through.
If it did create a mutable pointer, or if the value came from some other place the compiler has no knowledge about, then it would make a copy of the value before passing a pointer to foo1, just like it would do for the old ABI.
- mort96 5y agoI don't think you're correct here, but it's totally possible that I'm misunderstanding something. When generating code for `foo1`, the compiler has to know how the parameters are laid out. The code generated for `foo1` can't depend on the code which calls `foo1`. It is my understanding that the proposed ABI says that `foo1` will get `l` passed with a pointer, and that the term "immutable pointer" just means that `foo1` isn't allowed to modify the object through the pointer. The context (invisible to foo1) could look like this: struct large *lptr; void bar() { lptr->x += 10; } void do_thing() { struct large l = { ... }; lptr = &l; foo1(l); } So the compiler must assume that the call to `bar()` can modify the object pointed to by the "immutable pointer". --- Or are you suggesting that the callee's decision on whether to make a copy or not should be a runtime decision, and that the caller passes in information about whether the callee has to copy or not?
- Negitivefrags 5y agoAs you know, in do_thing you have taken a mutable pointer to l and placed it in a location where someone else could access it. Thefore, before the call to foo1, the compiler simply creates a copy of l, and then passes an immutable pointer to that to foo1. Effectively falling back to how the old ABI worked. The code generated for foo1 does depend on the code that calls foo1. That is what an ABI is. An ABI is a specification of the contract between the caller and the callee. The proposed new ABI says "If you are passing a struct by value, then you, the caller, will give me a pointer that you guarantee can't be modified until I return. In turn, I guarantee that I will not modify the pointer you give me."
- mort96 5y agoI think I understand what you're saying now, and where the confusion is. My understanding of the ABI was: "The callee will always receive a pointer to the caller's copy. If the callee can't guarantee that nothing modifies the caller's copy, the callee makes a copy." Your understanding is subtly different, because the caller guarantees that nothing else has a pointer to the parameter (and the caller guarantees that by making a copy when that's the only option). To be honest, I think the ABI according to my understanding is better. It does reduce the amount of cases a copy can be avoided, but it means that the worst-case is that one copy is made (by the callee). With your version, you would have a bunch of situations where the caller has to make a copy (because a pointer has escaped) and the callee has to make a copy (because it modifies the object). With my version, the worst-case is that a copy is made once (by the callee), but the worst-case would be hit more often. I think my understanding is closer to the intent of the article, due to this sentence: "In the event that a copy is needed, it will happen only once, in the callee, rather than needing to be repeated by every caller." In your version, the copy is sometimes made in the caller and sometimes in the callee.
- Negitivefrags 5y agoLook at the very next sentence. > The callee also has more flexibility, and can copy only those portions of the structure that are actually modified. It's clear that the author understands that the callee needs to copy any value it wants to modify. But also, your understanding doesn't actually work, due to the issue you mentioned. So I think it's pretty unreasonable to assume that is what the author meant.
- mort96 5y agoWait what issue are you referring to? My version absolutely works, it just falls back to making one copy a lot. In my version the callee can absolutely make a copy of only the modified fields if the function A) modifies some fields but not others and B) doesn't do anything which demands a full copy. Anyways, discussion on the intent of the article isn't super productive, I wrote a reply to https://news.ycombinator.com/item?id=27091726 https://news.ycombinator.com/item?id=27091726 which asks the author what their intention was.