How to avoid the 2 allocations for any struct?

Do not attribute the confusion to me. If you look at my message (the very first one in this thread)
I was just asking if there is a way to avoid the cost, allocation-wise, of doing things the proper way that you point out.

Your function that extends * annotated with @inline.

@inline function Base.:*(a::Perm,b::Perm)
    r=similar(a.d)
    @inbounds for (i,v) in enumerate(a.d) r[i]=b.d[v] end
    Perm(r)
end

Another function that uses extended *.

function foo(pa, b)
    sum((a*b).d)
end

It is optimized out with inlinining as suggested by @yuyichao.

julia> @btime foo($pa, $pb)
27.091 ns (1 allocation: 128 bytes)

It appears, though, @inline seems necessary for this context for no extra allocation. I am on Julia 1.1.0.

This SO question may be relevant to your inquiry. Note that your struct is immutable but not isbits-immutable.
https://stackoverflow.com/questions/43932741/stack-allocation-of-isbits-types-in-julia