One challenge you run into when creating constants is that it can be difficult to correctly initialize it to the value you want, because Rust does not allow initialization code that runs before main which you may be used to in C++. It has to be able to figure out the value at compile time.
Basically in order to call a function when initializing a constant, it must be const. This means that the compiler knows how to run it at compile time, so it can hard code the result in the exe file. The const_fn feature is a compiler feature that allows declaring a few more functions as const than currently possible in stable Rust.
Lazy static is a crate that provides a macro that allows you to make a constant which is initialized the first time you use it, which sidesteps the difficulties with initialization.
No, you can't allocate memory in const code because it is not possible to hardcode the constant in the executable as the data in the executable does not lie on the heap.
Basically const evaluation uses MIR which can emulate the rustc internal representation of Rust. There are quite a few checks on what you can do currently as they need to be very sure it's being implemented correctly. You can't even use if, match or any kind of loop in a const function.
As for things you can do with a const fn but not with a macro: If a struct has a private field but a const fn constructor, you can still create a constant of that type using the constructor, but you couldn't just type out the value because the field is private. playground