Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add VARRAY_FOREACH and VPTRS_ITER macros to iterate over arrays and pointer arrays #4239

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

nigoroll
Copy link
Member

These patches add two macros, semantic patches to start using them and the respective changes:

The VARRAY_FOREACH macro is intended to simplify loops over elements of an array using pointer arithmetic instead of an array index.

The usual pattern of iterating over the array index and then accessing the i-th element of the array is replaced with calculating the end pointer and looping over the array elements.

The macro basically implements

for (pointer = array, end = array + length; pointer < end; pointer++)

This pattern is more efficient but less clear to read when written out. The macro is similar to the *_FOREACH pattern which we already use in many other places with trees, lists and queues, but declares the loop variable locally.

The second macro VPTRS_ITER further simplifies our "array of pointers" case as, for example, used in struct strands.

Here, the loop variable is to be declared outside the macro to support keeping found elements from within the loop.

This macro is intended to simplify loops over elements of an array using pointer
arithmetic instead of an array index.

The usual pattern of iterating over the array index and then accessing the i-th
element of the array is replaced with calculating the end pointer and looping
over the array elements.

The macro basically implements

	for (pointer = array, end = array + length; pointer < end; pointer++)

This pattern is more efficient but less clear to read when written out. The
macro is similar to the *_FOREACH pattern which we already use in many other
places with trees, lists and queues, but declares the loop variable locally.

Remarks on the implementation:

- typeof() is now formalized with C23 but has been a GNU extension for long. We
  use typeof() since e1ac593 as of March 2021.

- The construct 'typeof(*(arr)) * var' (using the element type declaring a
  pointer on it) is used to un-const arr while keeping the constness of the
  element type: If arr is const, '(typeof arr) var = arr' does not work because
  var can not be modified.

  The additional (typeof(var)) cast is to avoid a Flexelint warning (reference
  to pointer).
The coccinelle patch only catches some cases, makes spatch enter a spinloop and
the patch result needs manual polish on top, but at this point the purpose is
only to show use cases for the new macro.
Based on VARRAY_FOREACH, this additional macro further simplifies the case of
arrays of pointer as, for example, used in struct strands.

Here, the loop variable is to be declared outside the macro to support keeping
found elements from within the loop.
we add a semantic patch to turn VARRAY_FOREACH cases into VPTRS_ITER cases where
applicable.
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.

1 participant