Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

ringabout
Copy link
Member

fixes #25116

@ringabout
Copy link
Member Author

It's really annoying for range types though, I would expect tons of misusages of ranges

let z: seq[range['a'..'z']] = @['c']

Otherwise stdlibs need a requireInit typetraits for using zeroDefault for types requiring explicit initialization

@Araq
Copy link
Member

Araq commented Sep 11, 2025

The stdlib should use more zeroDefault then, why would it need yet another trait.

@ringabout
Copy link
Member Author

ringabout commented Sep 11, 2025

proc arrayWithDefault*[T](size: static int): array[size, T] {.noinit, nodestroy, raises: [].} =
  ## Creates a new array filled with `default(T)`.
  for i in 0..size-1:
    result[i] = default(T)


proc setLen[T](s: var seq[T], newlen: Natural) {.nodestroy.} =
  ...
  for i in oldLen..<newlen:
    xu.p.data[i] = default(T)

arrayWithDefault and setLen need default to set default values for objects with default value fields or ranges types

@arnetheduck
Copy link
Contributor

arnetheduck commented Sep 12, 2025

zeroDefault

the only valid use of zeroDefault is when the location is not observable from the public api of the type - ie a table could in theory use it for its storage, for memory slots that are not yet in use - but that begs the question: if it's not observable, why would you want to zero it in the first place? it's better to leave it uninitialized in that case since zeroing costs (a lot) of CPU.

It also brings into light the bytes-to-type edge where a zeroDefault-initialized instance is in fact not a valid instance of the type and therefore should not be treated as such - in particular, it should be treated as bytes meaning that its memory should also not see destructors run on it etc - consider:

type MyType = object
  v: range[2..3]

proc `=destroy`(v: var MyType) =
  assert v in 2..3

This is a general problem with building collections in Nim in a world with semi-deterministic destructors - the naive approach of trying to ignore the bytes-to-type edge that was introduced in ORC has downstream effects on the soundness of other features - this is also why a correct Table implementation likely would be better of using a seq[byte] for its underlying storage - a statement that holds for any custom collection really.

@ringabout
Copy link
Member Author

ringabout commented Sep 15, 2025

It seems that It can make do by making the low bound value the default value of range types, e.g., simple range types only, like default(range[3..4])

The annoying cases are notnil and views types. Probably not touch them in this PR, e.g.

{.experimental: "views".}

proc split*(s: string, seps: set[char] = Whitespace,
                maxsplit: int = -1): seq[openArray[char]] =

@ringabout ringabout marked this pull request as draft September 19, 2025 13:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

default(T) breaks requiresInit requirements
3 participants