[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: manual improvement for next() [WAS: How undefined is undefined behaviour?]
- From: Viacheslav Usov <via.usov@...>
- Date: Thu, 10 Jun 2021 14:02:54 +0200
I am afraid the manual is either inconsistent or using the word
'undefined' in a special sense when it comes to next().
There are four general cases in the use of next(), specifically when
its second argument is:
1. Nil or absent.
2. An existing index.
3. An existing index whose value has been set to nil or another value.
4. An index that never existed.
(I used the word 'index' to mimic the manual in this particular case.)
The first three cases are almost completely documented by the manual.
What is not documented is what index is 'initial' and what index is
'next'. The latter is even specifically noted as to be unspecified.
The fourth case is not documented.
It is fairly obvious that the phrase 'if, during the traversal, you
assign any value to a non-existent field in the table' can only refer
to the first three cases, because during a traversal one calls next()
either with an index previously returned by next(), thus an existing
index, or with nil, or without one.
So by saying this behavior is undefined either the manual is
inconsistent or the manual re-asserts that 'the order in which the
indices are enumerated is not specified', which in the case of
simultaneous traversal and modification may obviously result in
missing some data, seeing some data again, and potentially looping
The 'nasal demons' undefined behavior would not arise.
Case four would actually be silently undefined behavior in next().
Should we assume we might get a "real" undefined behavior? I hope not,
because that means next() is an inherently unsafe function that must
be sandboxed. I would think that even in this case next() would return
either nil or an existing index/value pair, thus we have no undefined
behavior at all, but merely unspecified 'initial' and 'next' indices.
More generally, the manual could consider the case when next() is
called with completely random indices - should that go beyond
returning an existing index or nil? I would hope the behavior could be
described as follows:
A call to next() returns nil or an existing key with its associated
value. When called with nil, the return value is nil only when the
table is empty. Calling next() repeatedly on the key returned from a
previous call to next(), starting with nil, will enumerate all the
keys with their associated values, returning nil in the end, if no new
keys are added to the table between the calls to next(). A call
without the second argument is equivalent to a call with nil. The
order of the enumeration is unspecified and may change when new keys
are added during the enumeration, skipping some keys or returning them
multiple times, potentially infinitely if the modification continues.
(end - I used the word 'key' rather than 'index' because it seems more natural)
In any case, I hope the manual could be clarified.