-
-
Notifications
You must be signed in to change notification settings - Fork 98
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
Disallow Unsafe Declarations #229
base: master
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 |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# Disallow Unsafe Declarations | ||
|
||
| Field | Value | | ||
|-----------------|-----------------------------------------------------------------| | ||
| DIP: | | | ||
| Review Count: | | | ||
| Author: | [Mark]([email protected]) | | ||
| Implementation: | | | ||
| Status: | Draft | | ||
|
||
## Abstract | ||
|
||
Disallow extern C and C++ function declarations from being marked `@safe` or `@trusted`. | ||
|
||
## Contents | ||
* [Rationale](#rationale) | ||
* [Prior Work](#prior-work) | ||
* [Description](#description) | ||
* [Breaking Changes and Deprecations](#breaking-changes-and-deprecations) | ||
* [Reference](#reference) | ||
* [Copyright & License](#copyright--license) | ||
* [Reviews](#reviews) | ||
|
||
## Rationale | ||
|
||
Foreign code that is interfaced cannot be guaranteed to be safe. It should always be assumed as unsafe. Especially C declarations as the types used are not mangled into the name of the function. It would be possible to link to a C function with the incorrect parameter types. | ||
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.
That's the thesis of the DIP, the rationale section should explain in detail why that assumption is useful.
You can also link a D function with different signature by giving a false mangle. Once the OS / build system / foreign code is compromised, there's nothing the programming language can do, so I would say it's best to assume those behave well, because if they don't, all bets are off. 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’d use the last part to come to the very opposite conclusion. pragma(mangle, "body")
extern(C) void body_func() @trusted => safe_body();
void safe_body() @safe { … } It is a little lengthy, but it’s the shortest way which is honest. 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 tend to think a function definition should always be allowed to be It still does mean that a false |
||
|
||
## Prior Work | ||
|
||
Rust declares all foreign interfaces as unsafe, they cannot be explicitly marked as safe as there is only an `unsafe` keyword. [Rust avoids the issue of marking `unsafe` foreign declarations as `safe` entirely by design](https://doc.rust-lang.org/nomicon/ffi.html). | ||
|
||
## Description | ||
|
||
Any C or C++ function declaration with the `@safe` or `@trusted` attributes will now become an error. | ||
|
||
```D | ||
@safe extern(C) foo(); // Error: extern(C) declaration cannot be marked as `@safe`. | ||
@trusted extern(C++) bar(); // Error: extern(C++) declaration cannot be marked as `@trusted`. | ||
``` | ||
|
||
## Breaking Changes and Deprecations | ||
|
||
Any extern C and C++ declarations that are marked with `@trusted` or `@safe` will cause breaking changes. | ||
|
||
## Reference | ||
|
||
|
||
## Copyright & License | ||
|
||
Copyright (c) 2022 by the D Language Foundation | ||
|
||
Licensed under [Creative Commons Zero 1.0](https://creativecommons.org/publicdomain/zero/1.0/legalcode.txt) | ||
|
||
## Reviews | ||
|
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.
Not all extern C/C++ functions are foreign code.
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.
Unless there is a body it is foreign code. If you use C or C++ extern and access the function through a declaration instead of importing it, I don't think that should be a valid use case to consider. You can just import it instead or mark it as a D function and have a different wrapper for C/C++ if you need that.
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.
That's not true: