-
Notifications
You must be signed in to change notification settings - Fork 192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[cxx-interop] Document guarantees and assumptions for non-const C++ s… #816
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1271,6 +1271,20 @@ owned/guaranteed calling conventions. The C++ callers must guarantee that `x` is | |
Note that functions returning a shared reference type such as `returnSharedObject` transfer the ownership to the caller. | ||
The C++ caller of this function is responsible for releasing the object. | ||
|
||
If a C++ Shared Reference Type is passed as an argument to a C++ API from Swift, the Swift compiler *guarantees* that the passed value would be alive. Also Swift *assumes* that the C++ API is not consuming i.e., it returns with a valid object in the passed reference at the end of the C++ API call. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have a few comments on the wording and formatting:
|
||
|
||
```swift | ||
var obj = SharedObject.create() | ||
receiveSharedObject(obj) // Swift gaurantees that obj is alive | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo: |
||
``` | ||
|
||
```c++ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for explicitly specifying the language for code blocks! 👍 |
||
void receiveSharedObject(SharedObject *sobj) { | ||
... | ||
// Swift assumes that sobj is valid, non-null object at the end of this function | ||
} | ||
``` | ||
|
||
### Unsafe Reference Types | ||
|
||
The `SWIFT_UNSAFE_REFERENCE` annotation macro has the same effect as `SWIFT_IMMORTAL_REFERENCE` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fahadnayyar I would like to suggest these changes:
Can we add the following after this sentence.
... guarantees that the passed value would be alive, and retains ownership of the value. In other words, the argument is passed as +0 and there is no transfer of ownership.
Can we rephrase this as follows:
The C++ function is responsible for ensuring that the value pointed to by the parameter is alive during and at the end of the call. The C++ function should not assume it has ownership of the value and should do necessary retain operations if it is needs to take ownership.
If the argument is an inout (non-const reference) as shown below:
which would be imported in Swift as
If the C++ function overwrites the value of the argument with the new value, it is responsible for releasing the old value, and ensuring that the new value is properly retained so that the Swift caller has ownership of the new value when the function returns. Adhering to these rules is necessary to safely and correctly pass around SWIFT_SHARED_REFERENCE between Swift and C++. These rules are also generally recommended conventions to manage shared objects that use reference counting.