7
votes

Refer to Julia doc:

In Julia, all arguments to functions are passed by reference.

When I get the memory address of a Float64 argument from an anonymous function it looks right. but it's not true for a named function.

test = function (a::Float64)
    println(pointer_from_objref(a));
end
# => (anonymous function)
function test1(a::Float64)
    println(pointer_from_objref(a));
end
# => test1 (generic function with 1 method)
value=0.0;
println(pointer_from_objref(value))
# => Ptr{Void} @0x00007fe797c5c020
test(value)
# => Ptr{Void} @0x00007fe797c5c020
test1(value)
# => Ptr{Void} @0x00007fe799e83960

as @Gnimuc mentioned, there is another paragraph from Julia-Lang Doc that explains Argument Passing Behavior

Julia function arguments follow a convention sometimes called “pass-by-sharing”, which means that values are not copied when they are passed to functions. Function arguments themselves act as new variable bindings (new locations that can refer to values), but the values they refer to are identical to the passed values.

Is there any relation between this “pass-by-sharing” behavior and the above code?

2
AFAIK all the arguments to a function are passed by reference with the exception of plain data such as numbers and chars. Try to change your float number inside these functions... At the same time you've found something which contradicts that rule. Very interesting question. I look forward to see an answer.Maciek Leks
from doc: "Function arguments themselves act as new variable bindings (new locations that can refer to values), but the values they refer to are identical to the passed values." i'm wondering what does the term location mean here.Gnimuc

2 Answers

0
votes

From Julia documentation for pointer_from_objref(object_instance) function we get this description:

Get the memory address of a Julia object as a Ptr. The existence of the resulting Ptr will not protect the object from garbage collection, so you must ensure that the object remains referenced for the whole time that the Ptr will be used.

Check the following test:

x=10
y=10
println(pointer_from_objref(x)) # => Ptr{Void} @0x039ee2c0
println(pointer_from_objref(y)) # => Ptr{Void} @0x039ee2c0

As we can see pointer_from_objref fails to return native address of immutable objects and this is because this objects are pass by value, so I think the answer for above question is that pointer_from_objref was misused there.

0
votes

Expanding on Reza's answer, the thing to note here is that the "pass-by-sharing" reasoning does not apply to immutable objects. If you try the same code but using a vector of floats as a parameter you do get the expected behavior, ie, all pointers are the same:

    test = function (a::Vector{Float64})
        println(pointer_from_objref(a));
    end

    # => (anonymous function)
    function test1(a::Vector{Float64})
        println(pointer_from_objref(a));
    end

    # => test1 (generic function with 1 method)
    value=[0.0,0.1];

    println(pointer_from_objref(value))
    # => Ptr{Void} @0x0000000084601be0
    test(value)
    # => Ptr{Void} @0x0000000084601be0
    test1(value)
    # => Ptr{Void} @0x0000000084601be0