# Cannot delete a variable in a macro

**URL:** <https://discourse.julialang.org/t/cannot-delete-a-variable-in-a-macro/139804>\
**Category:** General Usage\
**Tags:** ccall, metaprogramming\
**Created:** [October 3, 2026, 9:10am UTC](https://discourse.julialang.org/t/cannot-delete-a-variable-in-a-macro/139804 "2026-10-03T09:10:21Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![aitzkora](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aitzkora/32/14610_2.png) [@aitzkora](https://discourse.julialang.org/u/aitzkora)\
**Post date:** [October 3, 2026, 9:10am UTC](https://discourse.julialang.org/t/cannot-delete-a-variable-in-a-macro/139804/1 "2026-10-03T09:10:21Z")

</div>

I want to simulate a allocation system trough the two following functions

```julia
alloc_float(n) = unsafe_wrap(Array, convert(Ptr{Float64},Libc.calloc(n, 8)), n)
macro free(p)
   :(Libc.free(pointer($p)); p = nothing) # does not work with $p = nothing
end

```

If I used the 2 functions

```julia-auto
julia> w = alloc_float(3)
3-element Vector{Float64}:
 0.0
 0.0
 0.0

julia> @free w

julia> w
3-element Vector{Float64}:
 2.86883399e-315
 2.90896374e-315
 1.6e-322

```

the `w` still remains in the Main space variable even if it points on bad memory area.  
The question here is about the macro and why it does not work, not about the pertinence of that two functions.

---

<div class="post-metadata">

**Author:** ![technocrat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/technocrat/32/220947_2.png) [@technocrat](https://discourse.julialang.org/u/technocrat)\
**Post date:** [October 3, 2026, 10:05am UTC](https://discourse.julialang.org/t/cannot-delete-a-variable-in-a-macro/139804/2 "2026-10-03T10:05:26Z")

</div>

It has to do with how Julia handles macro hygiene, expression evaluation order, and variable reassignment in outer scopes. `$p` correctly interpolates the variable name `w` into `pointer(w)`. However, `p = nothing` inside the quote block creates a local binding inside the expanded code block that doesn’t bind back to the caller’s variable `w`.

So, escaping is needed for memory de-allocation and re-binding in the calling context.

```julia
macro free(p)
    quote
        Libc.free(pointer($(esc(p))))
        $(esc(p)) = nothing
    end
end

```

That will make

```julia
@free w

```

return `nothing.`

---

<div class="post-metadata">

**Author:** ![aitzkora](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aitzkora/32/14610_2.png) [@aitzkora](https://discourse.julialang.org/u/aitzkora)\
**Post date:** [October 3, 2026, 10:07am UTC](https://discourse.julialang.org/t/cannot-delete-a-variable-in-a-macro/139804/3 "2026-10-03T10:07:42Z")

</div>

> [@technocrat](#):
>
> ```julia-auto
> macro free(p)
> quote
> Libc.free(pointer($(esc(p))))
> $(esc(p)) = nothing
> end
> end
> 
> ```

I found the following solution

```julia-auto
macro free(p)
  return eval(:(Libc.free(pointer($p)); $p = nothing))
end

```

but I prefer yours.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [October 3, 2026, 11:08am UTC](https://discourse.julialang.org/t/cannot-delete-a-variable-in-a-macro/139804/4 "2026-10-03T11:08:33Z")

</div>

That does something completely different. 99 times out of 100, if you use `eval` in a macro you are doing something very wrong!
