Iterators

Changes from Weak Checks

Differences

The anomalies detected in weak mode have been corrected:

Now, running LCLint with weak checking detects no errors.

Modules

Using Iterators

We had to suppress the modification errors because they used generators to go through a collection. Instead, we can use stylized iterators. This has the advantage that LCLint will check the definition and use of the iterator, and the iterator is now clearly documented.

The original code uses the for_ercElems macro to iterate through the elements of an erc. This requires modifying the erc, creating an instance of the ercIter type, and destroying the ercIter at the end of the loop to restore the erc to its original state.

Instead, we define an iterator that goes through each element of the erc, assigning a variable to the new element for each iteration. The specification for erc_elements is:

iter erc_elements (erc c, yield eref el);
This could also be expressed directly in the C source or header file, as:
/*@iter erc_elements (erc c, yield eref el);@*/
The yield parameter, el is assigned a value corresponding to a different elements of the erc each time through the loop.

Now we can rewrite the code to use the iterator. For example, the loop in _db_ercKeyGet:

eref _db_ercKeyGet (erc c, int key)
{
  eref er;
  ercIter it;
  
  for_ercElems (er, it, c)
    {
      if (eref_get (er).ssNum == key)
	{
	  erc_iterReturn (it, er);
	}
    }
  
  return erefNIL;
}
is rewritten as:
static eref _db_ercKeyGet(erc c, int key) 
{
  erc_elements(c, er)
    {
      if (eref_get(er).ssNum == key) return (er);
    } end_erc_elements ;
  return erefNIL;
}

The erc_elements iterator and its matching end are defined using macros:

# define erc_elements(c, m_x) \
  { erc m_c = (c); ercElem *m_ec = (m_c)->vals; unsigned int m_i = 0; \
    while (m_i < (m_c)->size) { \
      eref m_x = m_ec->val; m_ec = m_ec->next; m_i++;

# define end_erc_elements }}
Similarly, empset_elements, erc_elements and ereftab_element are used to iterate through other collection types.


Next: Continue to Standard Checks
Return to Summary