Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What exactly is "*const ()" in Rust?

Tags:

rust

So, what exactly is "*const ()" in Rust? It seems I can "as" some primitive value (integer value, function) to this type in Rust like the code shown below:

let foo = 1;
let pointer = foo as *const ();  // this works.

But for floating-point numbers and so on, the compiler doesn't allow us to do the above coercion, so what is "*const ()" in Rust? Is it similar to void* in C/C++? If so, why doesn't it support pointing to floating-point numbers?

BTW, adding the case where this pattern is currently used in the Reference: https://doc.rust-lang.org/std/mem/fn.transmute.html.

fn foo() -> i32 {
    0
}
let pointer = foo as *const ();  // here it is!!!
let function = unsafe {
    std::mem::transmute::<*const (), fn() -> i32>(pointer)
};
assert_eq!(function(), 0);
like image 232
Jason Yu Avatar asked Apr 13 '21 14:04

Jason Yu


People also ask

What is the point of const in Rust?

Constants represent values that cannot be changed. If you declare a constant then there is no way its value changes. The keyword for using constants is const.

What is the purpose of a const?

The const keyword specifies that a variable's value is constant and tells the compiler to prevent the programmer from modifying it.

What is the difference between variables and constants in Rust?

Variables are immutable by default but can be made mutable by using "mul" keyword while defining a variable. On the other hand, constant is always immutable and cannot be made mutable. Variables are defined using "let" keyword while constants are defined using "const" keyword.

How do you declare constants in Rust?

To declare a constant variable in rust, we use the const keyword followed by the name of the variable and its type. The syntax is as shown: const var_name: type = value; Note that you must explicitly specify the type of a constant variable, unlike normal variables in Rust.


2 Answers

*const () is very similar to C's const* void indeed, except for the fact that () represents exactly one value, while void represents no values. Relevant answer about difference between () and void

If so, why doesn't it support pointing to the floating-point numbers?

It does, it's just that foo as *const () has nothing to do with pointing to a float, it has to do with taking a value and converting it to a pointer with the same numeric value, which doesn't make sense for floats.

like image 142
Ivan C Avatar answered Oct 17 '22 00:10

Ivan C


The example just uses *const () as an arbitrary non-function pointer type, as it says:

Turning a pointer into a function pointer.

It would be exactly the same for an *const i32 or other types, but the authors needed to pick one and () is the simplest.

Is it similar to the void* in C/C++?

Not really. It's a pointer to (), which is a perfectly ordinary type (if zero-sized), and doesn't have special rules like void* does. See also

A Rust curiosity: pointers to zero-sized types

Final conclusion: arithmetic on a void* is illegal in both C and C++ (where arithmetic using .offset on a *const () is perfectly fine).

like image 2
Alexey Romanov Avatar answered Oct 17 '22 00:10

Alexey Romanov