How is copy! legal when the size of src and dst array are different?

How is something like this legal?

x = rand(2)
y = rand(3)
copy!(x, y) # in-place copying should be impossible.

This is somehow legal and leads to creation of a new array for x and y is then copied to x.
Shouldn’t this throw an error instead?

I am on Julia v1.9.4

you can use the macro @less to get an idea of what happened:

@less copy!(x, y)

function copy!(dst::AbstractVector, src::AbstractVector)
    firstindex(dst) == firstindex(src) || throw(ArgumentError(
        "vectors must have the same offset for copy! (consider using `copyto!`)"))
    if length(dst) != length(src)
        resize!(dst, length(src))
    end
    copyto!(dst, src)
end

so you can see x will be resized in-place

Oh boy. I didn’t expect this. There might be some silent bugs in my codebase :slightly_frowning_face:. Thanks.

copyto! is more conservative here:

julia> copyto!(x, y)
ERROR: BoundsError: attempt to access 2-element Vector{Float64} at index [1:3]

and so is .=:

julia> x .= y
ERROR: DimensionMismatch: array could not be broadcast to match destination

In consequence, I rarely use copy! for arrays.

5 Likes