TinyURL widget - shorten your URL's for free!

Enter a long URL to make tiny:

Tuesday, April 19, 2016

(NOT A SPOOF) C cheat sheet...

http://modelingwithdata.org/reference.html

http://www.catb.org/~esr/whatsnew.html

Monday, April 11, 2016

Creating and using a .this pointer in C language structs



This blog post contains examples of how to create a this pointer in C. You may know "this.xxxx" is a C++ attribute of objects. Well like many things you can emulate it in C because C is far more flexible without the bloating that object oriented languages provide for lazy programmers to make mistakes.

Of course, in order to emulate in C it requires more knowledge/experience than the average starting programmer can do. And as websites develop bit rot for older technology these things get lost unless others decide to pick up the challenge to maintain them.  I do not claim to be the first to do this, I am sure it's been done, but I am the one making a clear explanation and re-introducing it as it were.

I tried to post to stack exchange but I do not meet the process nazi's interpretation of a good question so I won't bother providing them my help. I would rather be helpful than process-correct and I don't get paid to educate so I stick to the facts without superfluity in a non-educational idiom.

<\whining>

One can make a resident pointer to a struct of the same type like so:
/*! \def cca_t continous cellular automata type
*
* state and cell variables are disconnected in order to
* uniformly maintain a common interface going forward.
* continuous / non totalistic / totalistic can augment this original struct
* dynamic variables can be integers converted or reals.
*
* convention is one state variable per neighbour starting at 0 will align
* with the number of neighboiurs and any above vars can be above n-1
*
* boundary cells can point at "zero" cell that provides no data save zeros
*
* neighbor number and state number reflect the same cell adjacent when assigning and using
* variables related to respective
* this allows each cell to be independent in orientation and position
* ( maybe a tunnel from far away lets out nearby)
*
* */
typedef struct cca_t
{
struct cca_t * this; //! point to myself.
unsigned int number; //! number of this cell
float x; //!
float y; //! absolute global X Y Z coords of cell centre
float z; //!
unsigned int neighbour_number; //! [0...N-1] number of cells surrouding this one
struct cca_t ** neighbours; //! dynamic pointers to surrounding cells.
int num_states; //! dynamic number of state variables per cell
cell_surface_t * state; //! dynamic state variables per cell
}cca_t;
view raw gistfile1.txt hosted with ❤ by GitHub


You don't need the first cca_t I just use it to make my understanding easier.

Before a struct has been defined one can't refer to it. Some sort of causal loop error in programming form.  But one can declare it as a struct while defining the struct- itself?!? Another metaphysical argument I don't need to go into. I know this will work on GCC with default warnings and error flags and that's all I care about. I cannot confirm if it works with C-XXXX standard in general terms. CAVEAT EMPTOR. If you do find out it works I would appreciate 40 ms of your time to respond back below and we can leave all the comments in one spot for people to find them. Like me in 6 months when I return.

So the "this" pointer is a pointer without an array. Notice I include a pointer to a pointer to  the same struct being defined. In this case I am making a same-typed pointer (to pointer) that will be the receptor of similar pointers from neighbouring cells. I was making a cellular automata at the time so that was the context. I wanted to be able to define modular units that might end up on different threads in this version. So they can access in the same program frame addressing but not necessarily the same operation unit / lightweight process.

So far so good. Now, when you initialize / construct the dynamic struct with malloc:

/*
* number of neighbors = num
* real coords x y z
* states = equals number of cell states should be more than num to reflect all
* */
cca_t *CCAInit(int num, float x, float y, float z, int states )
{
cca_t * ret;
int i;
ret = malloc(sizeof(cca_t) );
// point at self
ret->this = (cca_t *) ret;
ret->number = num;
// reset neighbors to none assigned
ret->neighbour_number = 0;
ret->x = x;
ret->y = y;
ret->z = z;
// allocate for a set of pointer to other cells
ret->neighbours = (struct cca_t ** )malloc(num * sizeof(struct cca_t *) );
// allocate for internal / external state pairs
ret->state = ( cell_surface_t * ) malloc(states * sizeof(cell_surface_t ) );
// number of states reflects the current empty cell surface
ret->num_states = 0;
return ret;
}
view raw gistfile1.txt hosted with ❤ by GitHub



You point the this at the pointer you will return at the end of the function.

In this instantiation, I make cell surfaces dependent on the same neighbour number to 0 cell means neighbour 0 and also state[0] for any values passed back and forth. Now I can iterate once and get it all.  I don't make a set pattern for cell walls because they might have arbitrary connectedness.

Now when I want to assign a neighbour to a cell it works something like this:

//! Assign neighbours to respective cell
int CCAAssignNeighbor ( cca_t *a, cca_t *b )
{
float * ptr;
// aim values - wow screwed this up a lot
// aim a's neighbour at b's this
a->neighbours[a->neighbour_number] = (struct cca_t * )b->this;
// vice versa
b->neighbours[b->neighbour_number] = (struct cca_t * )a->this;
// surrogate pointer assignment for a cell state to b cell state
ptr = &(b->state[b->neighbour_number]).st;
AssignCellSurface ( &(a->state[a->neighbour_number]), (const float *)ptr );
// vice versa
ptr = &(a->state[a->neighbour_number]).st;
AssignCellSurface ( &(b->state[b->neighbour_number]), (const float *)ptr );
a->neighbour_number++;
b->neighbour_number++;
return 0;
}
view raw gistfile1.txt hosted with ❤ by GitHub



I assign b's b->this variable to the neighbour slot open in a's neighbour list.
And likewise assign a's this to b. I also assign the cell walls (neighbour connection) using the ADDRESS OF of the pointer not the VALUE of the pointer. Since the neighbour is inside the larger struct passed and we are using  a pointer -> pointer -> struct we are accessing the value by default when we aim at the second struct within a struct that was passed inside a function variable declaration because these are nested structs within structs.  I know that sounds like double talk but I am unrolling the order of operations and presenting it in a way that when you look at other explanations will make sense.

Pointers take time to understand and remember that pointers give a value or an address, not an array, when accessed. That's why a pointer to element with offset indexing leads to another pointed-to element. An array is guaranteed for your program's sake (as far as it can see) to be a contiguous length of memory of type.

The struct is a value when accessed one way, it is an address when accessed the other.

I don't like the *( a + i).element method of writing C structs because it is a babyish technique taught by naive professors that have never dared to make more complicated nested code. Some claim it is faster and I don't dispute that but I doubt they've tried harder because they stop teaching at the semester end. Probably because when you present the same material every year no one challenges you to prove you can do more. It makes sense for basic applications which is what they can show you. But working code lives and gets more complex. Programmers don't.

I claim it's babyish because I dare them to keep this kind of nested logic straight in their mind when writing it.

*((((a+i)+j)+k)+l)+m).element

So

&(b->state[b->neighbour_number]).st

gives us the address of the pointed to state address (.st) inside the nested pointers and this can continue with a rational understanding of the content within like so:

&(b->state[b->neighbour_number]->neuron[b->cell_number]->synapse[b->geo_number]).st

ad infinitum with a rational way to understand what was written. I can make iterator names that make sense and I can understand 10 files all at once. All the element indices can be maintained at the top level and iterated which is really the operation that most code undergoes. But what is different here is people can make a direct understanding of the things operating on things because that is the level humans work at. That is what costs the most time; understanding what code does not writing perfect code. Machines are better in most cases for optimization except for ATLAS as far as I know. R. Clint Whaley is an uber nerd and he writes sparse matrix optimizations by hand.

I follow the unix philosophy  writing understandable code and leaving optimization as another step:

"Worse is better"

I work in research so I don't worry about development as much as making sure it works. But with a top level iteration mechanism the GCC compiler can then unroll for loops for speed or optimize for memory. But the human being writes code and then goes off for 3 months and then has to come back to it.

This is why writing things like a .this pointer make it easier to grasp what you wrote and then evolve it quickly with patterns that make sense.