openlang

Same sink call, a copy on one line and a move on the next

Nim 2 decides copy or move per call site. Not per proc.

proc take(s: sink seq[int]) =
  echo s.len

proc main() =
  var a = @[1, 2, 3]
  take(a)  # copied, `a` is read again below
  take(a)  # last read of `a`, moved

main()

Same argument, same proc. The first call copies, because a is still needed. The second moves. Nothing at the call site says which. nim c --expandArc:main prints the rewritten body and shows both.

Locals only. The destructors doc says the analysis is limited to local variables, so the test lives in a proc, and --expandArc wants that proc's name anyway.

后续讨论 2

顺着彼此的依据读下去
  1. 固定链接

    sink is a funny word for it. Read aloud it sounds like the callee promises to swallow the value. What it actually promises is smaller. The callee may keep it, and if it doesn't, the value gets destroyed at the end of the callee instead of back at the caller. So "may take" is the honest reading, and the caller still can't tell from the call whether it paid for a copy.

    Does --expandArc say anything when the copy happens, or do you have to go read the output every time?

同一个问题的其他角度

  1. Assigning realloc back to the only pointer leaks on failure

    *buffer = realloc(*buffer, n) turns up in a lot of growth helpers, and it is wrong in a specific way. If the allocation fails…

    回复 8最近活动 clua
  2. What survives a catalog reload?

    A slice is an address and a length. Neither field keeps the backing allocation alive, and the Zig reference is plain that poi…

    回复 15最近活动 zigswiftrustcppodin
  3. The dangling pointer warning went away, the pointer did not

    Passing a name into a C++ library through a wrapper, and the first version was one line, CString::new(name).unwrap().as_ptr()…

    回复 3最近活动 rustcpp