Skip to content

Commit b3ac3ef

Browse files
barcharcrazemilio
authored andcommitted
Replace confusing note in cpp.md on "RVO"
The original commit adding this note referenced #778, but then went on to talk about how the problem was RVO and that the problem is not possible to solve in bindgen because bindgen can't know if RVO happened or not. However this is incorrect in several ways. The problem in #778 has nothing whatsoever to do with RVO but rather with bindgen simply not understanding the calling convention for passing or returning types that are "non trivial for the purposes of calls". This is completely consistent and does not depend on what the optimizer decided to do (after all, if callsite side calling-convention did depend on what the optimizer happened to do inside the function it would be impossible for C++ compilers to emit correct calls to external C++ functions!). You can see this quite clearly [here](https://godbolt.org/#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAMzwBtMA7AQwFtMQByARg9KtQYEAysib0QXACx8BBAKoBnTAAUAHpwAMvAFYTStJg1DIApACYAQuYukl9ZATwDKjdAGFUtAK4sGIM6SuADJ4DJgAcj4ARpjEEgDspAAOqAqETgwe3r7%2ByanpAiFhkSwxcVyJdpgOGUIETMQEWT5%2BAVU1AnUNBEUR0bEJtvWNzTltwz2hfaUDFQCUtqhexMjsHAD06wDUACoAnkmYW3tLxFtoWFsIsZikWyRbtKhM6FuGW5iqrEn0AHQmGgAggoCMQvA4tgRMCCokwlFsTPErPEACImADMViBILBEKhIIRSIBgK2pMh0IIEDmGKxJLJ%2BMpaAYBIZ5gAbNTMcSyVsAG6oPDoABUkJpxMRaK5QIZWwUAEcvA1MFTCbSeTKCIjkZK1WTiJgCMsGKKpYCJeKgaECFsWExQiqtdz6RTIQj0SjZQqlVSxUCnaT9YbiMa0gAvTCoKgQBmc2kSjgLWicACsvD8HC0pFQnDc1msstOqwRZnRPFIBE0CYWAGsQOj0b9603my22fpOJI05Ws5xeAoQBpy5WFnBYEg0CwknRYuRKBOp/Q4sAFMwkgoEKgCKQsLy8KsAGp4TAAdwA8od02WaLQocR%2BxAot2oqEGntOGWJ2xBKeGLQ3xneCwW0jHEADtzwfUal5aFu0%2BaovChd9eCtTAkzA2g8CiYhXw8LBu1BPAWCQhYqAMZdDxPc9GCQmRBBEMR2CkWj5CUNRu10Lh9EMYw80sfRMP7SAFlQJJHAEfsOD7VDqjEvwIFcUY/E44IphKMo9BSNJZMUjT8lk3o1NmWxpI6BguhGTwWj0dpZPMyZin6cohm6HTOJBboDMciQFgUQtGMTFMuzA7MOC2VQAA42QAWjZSQtmAZBkC2aMwQYas5mS3BCAecxSzmXgKwAuYazrBsW3Kps2zQztSHTTMQr7AchyK0hR0QFBUEnacyAoCB526kBl1XddN23TBdwPI8zwvGjr1ve9HzA59mGIf8P06r8CB/P9uyA7jQMzfBIMcaCJMzODkAQtYyxQtDMwwrCcIwNZMwIojuATPgyIUCjpuoj7mPo8QmP4QRFBUdQwN0AIDCMFBeJsB7BKpLNRIyCSoqoBhUCi1DBUwKKmRxcEiDvKT7FklwGHcSycmU6nPJmJzNIKTJaaUvItIyRn1LckzbImVzjIp2oJh5oz3Is7IOcl%2Bzpl5ny/O89sOFTWruxCsLIpiuKEqSlKvDSjKICy0nizygrhxK%2BtGwq8qVZqureAa2wmsKrRipVswgvq3tmo9hZoLvDIQEkIA) Notice how the body of `main` is identical no matter if copy elision is enabled or not. To get `test` passed in a register you must remove the copy constructor. I spent a few hours being really confused by this note before I tracked down the original PR and realized what it was trying to talk about. Hopefully this saves the next person to come across it the same trouble. As an aside I suspect the clang c bindings can already give you information on special member functions and base classes, making it fairly easy to do this correctly. AFAICT bindgen already does not rely on llvm's code generation facilities to figure out the ABI of calls for C (except perhaps indirectly, via rustc), so this seems reasonable to just do in bindgen, explicitly.
1 parent d86db07 commit b3ac3ef

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

book/src/cpp.md

+7-4
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,10 @@ cannot translate into Rust:
7272
[the tracking issue for exceptions](https://github.com/rust-lang/rust-bindgen/issues/1208)
7373
for more details.
7474

75-
* Return value optimization. C++ compilers will in certain circumstances optimize functions
76-
returning a struct type value to instead take an extra hidden argument that refers
77-
to the return value struct. `bindgen` cannot necessarily know about this optimization and
78-
thus at present `bindgen`-interfaces for these kinds of functions are invalid.
75+
* Many C++ specific aspects of calling conventions. For example in the Itanium abi types that are
76+
"[non trivial for the purposes of calls](https://itanium-cxx-abi.github.io/cxx-abi/abi.html#non-trivial)"
77+
should be passed by pointer, even if they are otherwise eligable to be passed in a register.
78+
Similarly in both the Itanium and MSVC ABIs such types are returned by "hidden parameter", much like
79+
large structs in C that would not fit into a register. This also applies to types with any base classes
80+
in the MSVC ABI (see [x64 calling convention](https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170#return-values)).
81+
Because bindgen does not know about these rules generated interfaces using such types are currently invalid.

0 commit comments

Comments
 (0)