3 ms·
Even if the called function (call it B) does use the object as an argument for another function it calls (call it C), B could end up having to perform another c
by comex 5y ago
Even if the called function (call it B) does use the object as an argument for another function it calls (call it C), B could end up having to perform another copy for that call, if B also takes a pointer to the variable at some point and lets it escape. Or a pointer to any part of the variable.
And it’s not limited to mutable pointers. Sure, if the variable itself is marked const, then it’s UB to modify it. But const local variables are rare in most codebases, in my experience. If on the other hand you pass the address of a non-const variable as a function argument, even if the type of the argument is a const pointer, the function can legally cast away the const and write to the pointer.
Still, I agree that this would probably eliminate more copies than it creates. But I don't think it would eliminate or create very many copies. In my experience, approximately nobody writes code that passes structs by value in the first place.
- derefr 5y agoYou know what this would mostly affect? Code that passes longs or doubles by value, when compiled for 32-bit architectures (like many modern ARM microcontrollers still are.) Something doesn’t have to be a struct to be larger than a machine register.
- derefr 5y agoAlso, FYI (sibling post because my first one is already locked): this isn't about what the programmer tells the compiler. It's about what the compiler can infer on its own, through dataflow analysis. "const", as a qualifier, isn't novel information about a variable for the compiler — compilers already know whether a variable is used mutably or not, just like they know when and where a variable has its last access and goes dead. "const" is an instruction to the compiler that if it finds, by its own independent analysis, that the variable cannot be const in that context, then the program is invalid and compilation should error out. As such, "const" only even has a meaning, if the compiler already independently knows which declared variables are or are not const "in practice." That information is what would be used to decide whether to do the copy. > B could end up having to perform another copy for that call At worst, that's no worse than what happens under the current ABI, where A passes data by value to B, which passes it by value to C. (Do also remember, as I said in another comment, that ABIs/calling conventions are only "about" functions with external linkage. Functions with "static" linkage do whatever the compiler likes; as do their callers.) I think, in the specific situation you're describing, there's also prelink-time cross-unit optimizations that can be done here to eliminate redundant copies even further — but that's getting close to just expecting C to do Rust-like ownership analysis, so I wouldn't claim that to be practical in any production compiler in the near future.