1

Say I have a variable:

let a = ref 3 in magic_code

Magic_code should print the address in memory that is stored in a. Is there something like that? I googled this but nothing came up...

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
dreamer_999
  • 1,465
  • 3
  • 17
  • 22
  • 8
    You can't do this in the safe part of OCaml. Also, addresses of things change all the time due to garbage collection. Why do you want to know the address? – Jeffrey Scofield Oct 31 '13 at 16:21
  • I see. For debugging purposes. – dreamer_999 Nov 01 '13 at 02:16
  • @bigollo: You can see if two variables point to the same thing by using `==` and `!=`. Other than that, there's not much you can do. – newacct Nov 01 '13 at 23:19
  • Yes, I know that. I guess you have to appreciate the abstraction of ocaml. – dreamer_999 Nov 01 '13 at 23:25
  • 1
    If you don't want to give up despite the above pronouncements, learn about the `Obj` module. If you're desperate to use it for debugging, setting a large heap may help for not having the GC kick in. – lukstafi Nov 02 '13 at 15:36
  • *But*, the fact that you need to debug the use of `ref`s means that you're doing it wrong, style-of-programming-wise. It's OK to use mutability as long as it is local and/or closely models the logic of your problem. – lukstafi Nov 02 '13 at 15:45

1 Answers1

4

This should work:

    let a = ref 3 in 
    let address = 2*(Obj.magic a) in
    Printf.printf "%d" address;;

OCaml distinguishes between heap pointers and integers using the least significant bit of a word, 0 for pointers and 1 for integers (see this chapter in Real World OCaml).

Obj.magic is a function of type 'a -> 'b that lets you bypass typing (i.e. arbitrarily "cast"). If you force OCaml to interpret the reference as an int by unsafely casting it via Obj.magic, the value you get is the address shifted right by one bit. To obtain the actual memory address, you need to shift it back left by 1 bit, i.e. double the value.

Also see this answer.

Community
  • 1
  • 1
user2361830
  • 974
  • 7
  • 7
  • I'm not the downvoter, but I think that code will interpret the value as an OCaml int (shifted one bit left), so you'll need to double it to recover the actual pointer. And, obviously, this is a huge and unreliable hack, only useful in emergencies for debugging. – Thomas Leonard Dec 29 '13 at 13:46
  • `Obj.magic`, `Obj.repr`, `Obj.obj` are all implemented as identity functions. They only differences are their type. `Obj.magic` is already a function from any type to any type. So an `Obj.repr` is unnecessary. – newacct Jan 23 '14 at 19:56
  • Multiplying it by 2 will lose the most significant bit of the address – newacct Oct 09 '14 at 00:33