You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This keeps coming up in our internal discussion occasionally, but there are some corner cases where they're not equivalent (I think in static initializers, I have to look up the original discussion for details). Meanwhile, you can do the following with c2rust-refactor:
rewrite_expr '0 as *const $t:Ty' 'std::ptr::null()' ;
rewrite_expr '0 as *mut $t:Ty' 'std::ptr::null_mut()' ;
I also recall the two not being equivalent. I wonder if it was just because it wasn't a const fn at the time? Maybe it'd be viable now, but I'm not certain
One reason why they wouldn't be equivalent is static promotion. 0 as *mut T can be directly promoted to consts and statics. On the other hand, ptr::null_mut is a const fn, and const fn calls in general cannot be safely promoted. The specific functions ptr::null and ptr::null_mut are rustc_promotable, but this may change in the future and is harder to track for the refactoring tools. I think it's unlikely that the transpiled code will depend on static promotion (it's more of a syntactic sugar), but avoiding such code is still reasonable.
Also, being function calls they may be harder in general to analyze. Knowing that they are really null requires either interprocedural analysis (which may be intractable in general) or special-casing.
Finally, these function calls shouldn't even normally appear in idiomatic Rust code. They are generally an artifact of partial initialization, redundant default-initialization (which should be folded away) or nullable pointers (which are better expressed as Option<&T> or Option<NotNull<T>>). For this reason optimizing for their readability seems counterproductive, they should be optimized for easy elimination.
I think this should be re-considered, as 0 as *const T and null() are no longer equivalent under strict provenance. We should prefer null() and null_mut() where possible to avoid the int-to-ptr casts. For example, miri warns about this, and can't catch all UB under permissive provenance. Where we do need an int-to-ptr cast, we should use the ptr::from_exposed_addr API to make this explicit, not just an as cast.
Activity
ahomescu commentedon Nov 18, 2019
This keeps coming up in our internal discussion occasionally, but there are some corner cases where they're not equivalent (I think in static initializers, I have to look up the original discussion for details). Meanwhile, you can do the following with
c2rust-refactor
:TheDan64 commentedon Nov 18, 2019
I also recall the two not being equivalent. I wonder if it was just because it wasn't a const fn at the time? Maybe it'd be viable now, but I'm not certain
ahomescu commentedon Nov 18, 2019
I checked last night,
null
andnull_mut
have been const fns since 2015.TheDan64 commentedon Nov 18, 2019
Hmm. Guess it wasn't that, lol
afetisov commentedon May 23, 2022
One reason why they wouldn't be equivalent is static promotion.
0 as *mut T
can be directly promoted to consts and statics. On the other hand,ptr::null_mut
is a const fn, and const fn calls in general cannot be safely promoted. The specific functionsptr::null
andptr::null_mut
arerustc_promotable
, but this may change in the future and is harder to track for the refactoring tools. I think it's unlikely that the transpiled code will depend on static promotion (it's more of a syntactic sugar), but avoiding such code is still reasonable.Also, being function calls they may be harder in general to analyze. Knowing that they are really null requires either interprocedural analysis (which may be intractable in general) or special-casing.
Finally, these function calls shouldn't even normally appear in idiomatic Rust code. They are generally an artifact of partial initialization, redundant default-initialization (which should be folded away) or nullable pointers (which are better expressed as
Option<&T>
orOption<NotNull<T>>
). For this reason optimizing for their readability seems counterproductive, they should be optimized for easy elimination.ptr
null pointer APIs instead of hardcoded 0s #620kkysen commentedon Aug 26, 2022
I think this should be re-considered, as
0 as *const T
andnull()
are no longer equivalent under strict provenance. We should prefernull()
andnull_mut()
where possible to avoid the int-to-ptr casts. For example,miri
warns about this, and can't catch all UB under permissive provenance. Where we do need an int-to-ptr cast, we should use theptr::from_exposed_addr
API to make this explicit, not just anas
cast.analysis/test
#6822 remaining items