# A (pure) C extension

Posted on March 12, 2014 by phimuemue

Over three years ago, I came across a little problem and was able to write a header file for C++ that allowed the programmer two write things like the following:

10 times {
do_something_here();
}

This did exactly what you would expect from what it read. Additionally, the implementation had support for an implicitly generated counting variable denoted by a single underscore. The only drawback: It was only for C++.

Now, over three years later, I can claim that I have found a way to implement (at least to some extent) the original thing in pure C.

The header file itself is not that large at all:

volatile char _A[19] = {0};
#define _Y 10
int _D=0,_O=0,_S=0,_M[_Y],_C[_Y],_L;
#define _ _C[_D]
#define times [_A]=1;_D++;_S=0;for(_S \
=-1;_A[_S]==0;++_S){ _M \
[_D]=_S+1;}_A[_S]=0;for \
(_C[_D]=0;_O=_D,(_L=!!( \
_C[_O]<_M[_O] )),_C[_O] \
==_M[_O]?_D--: 1,_O=_D, \
_L;_=_C[_O]++)

You can paste this into a header file that can be included in other C source files to support the features described now.

## Usage

Let me show some sample code to illustrate what the extension can do:

#include<stdio.h>
#include"extension.h"

int main(int argc, char** argv){
3 times printf("Hello.\n");
3 times printf("Score: 0 : %d\n", _);
2 times {
printf("Counting: ");
9 times printf("%d ", _);
printf("\n");
}
5 times {
printf("Counting up to %d: ", _);
_ times printf("%d ", _);
printf("\n");
}
return 0;
}

### Features

• Simple notation of simple loops (in the style depicted above)
• Counter is implicitly stored in a variable called _ (a simple underscore).
• Nesting of loops allowed.

### Restrictions

• Works only for a certain number of loops. Current implementation supports a maximum of 18 iterations (higher values result in undefined behaviour). Can be adjusted in header file by changing the size of array _A.
• Only a certain nesting depth is allowed. Current implementation supports a nesting depth of 10. Can be adjusted by redefining the macro _Y.

## Implementation details

#define MAXSIZE 20
volatile char counterarray[MAXSIZE] = {0};

#define MAXDEPTH 10
int depth=0;
int olddepth=0;
int searcher=0;
int searchermax[MAXDEPTH];
int counter[MAXDEPTH];
int lastloop;
#define _ counter[depth]
#define times [counterarray]=1; \
depth++; \
searcher = 0;\
for(searcher=-1; counterarray[searcher]==0; ++searcher){ \
searchermax[depth]=searcher+1; \
} \
counterarray[searcher] = 0; \
for(counter[depth]=0; \
olddepth=depth, \
(lastloop=!!(counter[olddepth]<searchermax[olddepth])), \
counter[olddepth]==searchermax[olddepth]?depth--:1, \
olddepth = depth, \
lastloop; \
_=counter[olddepth]++)

The implementation itself basically has to keep track of the following:

• Current nesting depth
• Current nesting depth's counting variable

It does so by defining a macro times. This macro then takes all actions necessary to support the desired behaviour:

• Retrieving upper iteration bound: The basic idea is to have an array of chars that are initially all set to 0 (this is the array counterarray). If we issue a call to e.g. 2 times {do_it;}, the macro times shall set the second element of counterarray to 1 (i.e. counterarray[2] = 1). In C, it is possible to swap index and array name in such an assignment, so we can write 2[counterarray] = 1 to acchieve the same. This is exactly what the macro times does as first step. Then, we can later scan the array counterarray until we find an element that is not 0, but 1. The corresponding index is then the upper iteration bound. It is stored in variable searcher. Since we want to support nesting, we have to store the upper bound for each nesting depth separately, this is done by searchermax[depth]=searcher+1.
• Adjusting current nesting depth: As said, we want to support nesting of loops, so we have to keep track of the current nesting depth (done in the variable depth). We increment it by one if we start such a loop.
• The actual counter variable: We have a "variable" called _ that implicitly gets assigned the current counter. In fact, we store one counter for each nesting depth (all stored in the array counter. Then, _ is just another macro that retrieves the proper counter for the current nesting depth from this array.
• The actual for loop: We take the for loop into parts:
• We initialize the counter for the current nesting depth to 0 (done by counter[depth] = 0).
• The iteration step is the most complicated part: We have to check if the loop at the current nesting depth has reached its end. If so, we have do update the nesting depth accordingly. If not, we have to increment the current nesting depth's counter by 1. The variable lastloop is 1 if this is the last iteration, otherwise 0, and we adjust the current nesting depth accordingly. The main problem here is that we have to write this as a sequence of expressions, all separated by commata, which requires us to write all these conditions in a very non-straight-forward way.
• The "increment step" of the for loop consists of only one assignment, that increments the appropriate counter (i.e. the element of counter of the proper nesting depth) and assigns this value to our "counter variable" _.