Dereferencing untyped raw pointer


Why does dereferencing a typed raw pointer requires an unsafe block

fn main() {
    let raw_p: *const i32 = &10;
    assert!(*raw_p == 10);
[Output] 3:19 error: dereference of unsafe pointer requires unsafe function or block [E0133]     assert!(*raw_p == 10);
<std macros>:1:1: 5:46 note: in expansion of assert! 3:27 note: expansion site
error: aborting due to previous error

while dereferencing an untyped raw pointer doesn’t?

fn main() {
    let raw_p = &10;
    assert!(*raw_p == 10);


&10 gives you a safe pointer (reference) &i32, not raw pointer *const i32 . I.e. the second example is equivalent to

fn main() {
    let raw_p: &i32 = &10;
    assert!(*raw_p == 10);

At the same time &i32 is implicitly convertible to *const i32, so let raw_p: *const i32 = &10; compiles too, but &10 is converted to *const i32.


Ok, thank you. I was getting confused because in gdb I had seen (i32 *) as the type for raw_p in the example:

fn main() {
    let raw_p = &10;
    assert!(*raw_p == 10);
(gdb) ptype raw_p
type = i32 *


At runtime, there is no difference between a reference and a pointer, AIUI.

Types in general in most compiled native languages are a wholly compile time concept.


Yes, at runtime there are only addresses and data. But I guess that the debugging data contains some information about the data types. At least with C++ I get the following gdb output:

#include <iostream>

int main()
  int* p = new int;

  int& r = *p; 

  std::cout << "p: " << p << std::endl;
  std::cout << "r: " << r << std::endl;
(gdb) ptype p
type = int *
(gdb) ptype r
type = int &


That will probably change in the future, but currently gdb doesn’t know anything about Rust.