Comments (18)
I also agree to keep unsafe narrow for numeric types and have something else for the rest... having narrow in the name when casting a pointer is extremely confusing
from cppfront.
In what cases is casting a u8* to void* or the other way around unsafe?
casting a void *
to a u8*
is unsafe if the pointer refers to something other than a u8
or an array of u8
.
from cppfront.
btw I do agree that just having cpp2::unsafe_narrow
is not enough, perhaps that one needs to be locked and usable with integral types only, and we need another one maybe called cpp2::unsafe_type_cast
that does what the usual static_cast
does, which only works for type casting (so anything but integral types).
from cppfront.
Thanks again for this suggestion! OK, here's a draft of what I'm about to push, after also adding test cases and a Clang pre-16 workaround:
Restrict unsafe_narrow
, add unsafe_cast
Restrict unsafe_narrow
to narrowing cases and arithmetic types
Make as
diagnose unsafe pointer casts, with a message to use unsafe_cast
instead
Allow both unsafe_narrow
and unsafe_cast
to be used without cpp2::
qualification in Cpp2 code
Remove some uses of unsafe_narrow
in cppfront's own code that weren't actually narrowing
Example:
f: (i: i32, inout s: std::string) = {
// j := i as i16; // error, maybe-lossy narrowing
j := unsafe_narrow<i16>(i); // ok, 'unsafe' is explicit
pv: *void = s&;
// pi := pv as *std::string; // error, unsafe cast
ps := unsafe_cast<*std::string>(pv); // ok, 'unsafe' is explicit
ps* = "plugh";
}
main: () = {
str: std::string = "xyzzy";
f( 42, str );
std::cout << str; // prints: plush
}
from cppfront.
Can unsafe_cast
be used for things beyond pointers? If not, should it be unsafe_pointer_cast
? If so, would it make sense to have a pointer specific one, so it's obvious that there is no physical conversion?
from cppfront.
from cppfront.
I just realized there's cpp2::unsafe_narrow
, but to my understanding casting void *
to [unsigned] char *
is safe... so it's misleading IMHO... feel free to close if I'm wrong about this, prefferably with an explanation as to why.
from cppfront.
I think reinterpret_cast
ought to work? At least I see union
's implementation using it with no issues...
from cppfront.
static_cast works... so does reinterpret_cast but that's more loose, my issue was that it's unintuitive... because we are banned from using them in pure syntax and mmap(...) as *u8
crashes instead of doing a static cast and makes me do cpp2::unsafe_narrow for a case that should not be unsafe?!
from cppfront.
This is my opinion: Sure, the operation is safe in this specific instance, I mean, if you narrow an integer, that's only "unsafe" if you are losing information by the narrow, which is not most cases. Here the problem is that the compiler has no way to prove that casting the mmap
's void*
is safe, therefore you need a escape hatch to really say "yes, I know what I am doing!". The verbose cpp2::unsafe_narrow
(or whatever other cast you might use) makes this pop out more for awareness, and I think that's the intended design.
from cppfront.
Thanks! Right, as
is intended for safe casts. For casts that are unsafe, my preference is to make people write unsafe_
. I didn't realize that unsafe_narrow
can be (ab)used for that (ha! cute) but I like @DyXel 's suggestion (and was about to say the same but with the name unsafe_cast
... maybe unsafe_type_cast
is even better though, verbose is good for important/dangerous operations):
btw I do agree that just having
cpp2::unsafe_narrow
is not enough, perhaps that one needs to be locked and usable with integral types only, and we need another one maybe calledcpp2::unsafe_type_cast
that does what the usualstatic_cast
does, which only works for type casting (so anything but integral types).
from cppfront.
the compiler has no way to prove that casting the mmap's void* is safe
In what cases is casting a u8*
to void*
or the other way around unsafe?
from cppfront.
unsafe_cast
works for anything you can static_cast
, such as casting away const
and pointer <-> integral conversions. So, more than pointers I think?
from cppfront.
I was wondering if it could somehow be a bit more descriptive of exactly what it's doing, and that would make it more self-documenting.
For example, unsafe_pointer_cast
only works if the source and destination pointers are the same size, so you know there is no data loss such as casting an int*
to u8
, and no user-defined conversion operators could be invoked.
It would also be great if it could report an error or at least a warning if you are using it somewhere that it's not needed, such as casting from int*
to void*
or derived*
to base*
. If it's being used where it's not needed, someone could come across it, see that it reports that it's doing something unsafe, and spend time trying to figure out why it's unsafe, when it could just be removed.
from cppfront.
For example, unsafe_pointer_cast only works if the source and destination pointers are the same size, so you know there is no data loss such as casting an int* to u8, and no user-defined conversion operators could be invoked.
What about casting void*
or char*
to anything else. Here, the size of the input pointer and output pointer would be always different. Adding this restriction would actually make it a dynamic_cast
.
from cppfront.
What about casting void* or char* to anything else. Here, the size of the input pointer and output pointer would be always different. Adding this restriction would actually make it a dynamic_cast.
I don't know of any modern architecture where sizeof(void*)
and sizeof(char*)
are different. Are you thinking sizeof(void)
and sizeof(char)
?
from cppfront.
I meant void*
to anything else or char*
to anything else. Both of these cast will change the size of the underlying type.
from cppfront.
I meant void* to anything else or char* to anything else. Both of these cast will change the size of the underlying type.
They change the size of the underlying type, but not the size of the pointer itself, which is what I was talking about. There is no truncation in converting the pointer itself, as there would be if you cast char*
to u16
. The "changing the size of the underlying type" is covered by this being unsafe_
. That's also why this isn't needed for foo*
to void*
or derived*
to base*
.
from cppfront.
Related Issues (20)
- [SUGGESTION] Add the equivalent of C++23 "deducing this" HOT 10
- [SUGGESTION] Only include `cpp2regex.h` when `@regex` is used to improve compile time HOT 5
- [BUG] raw string literals are not respected when lowered
- [SUGGESTION] clean up extra whitespace at the end of line for generated code
- [BUG] ICE when putting a ; after a type definition when there is a newline in the type body HOT 6
- [DOCS] Improve documentation on syntax for function return types
- [SUGGESTION] Allow `swap` to be a hidden friend
- [SUGGESTION] allow `: ==` for anonymous alias declarations (instead of `using`) HOT 7
- [BUG] using the using keyword inside a namespace with global functions results in code that does not compile
- [BUG] using using for operators fails
- [SUGGESTION] Documenting `==` as `constexpr` and using unified declaration syntax for aliases HOT 8
- [BUG] Confusion between postifx and binary use of `&` and `*` when keyword is part of the second argument. HOT 1
- [SUGGESTION] Creating an enum instance from a raw integer HOT 6
- [SUGGESTION] add special cases for [unique.]new and shared.new when using custom deleters
- [BUG] Constant static members not initialized inside class definition
- [BUG] New clone of repo shows modification to `pure2-regex_10_escapes.cpp.execution` HOT 5
- [BUG] Regression output dpends on temporary directory HOT 1
- [BUG]
- [BUG] Error when i try to build cppfront HOT 2
- [BUG] Definite last use and lvalue reference constructor generates wrong code? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cppfront.