Michael S <
already5chosen@yahoo.com> writes:
On Fri, 29 Mar 2024 23:58:26 -0700
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>
I did program in FORTRAN briefly but don't remember ever using
computed GO TO. And yes, I found that missing semicolon and put it
back. Is there some reason you don't always use -pedantic? I
pretty much always do.
>
Just a habit.
In "real" work, as opposed to hobby, I use gcc almost exclusively for
small embedded targets and quite often with 3-rd party libraries in
source form. In such environment rising warnings level above -Wall
would be counterproductive, because it would be hard to see relevant
warning behind walls of false alarms.
May be, for hobby, where I have full control on everything, switching
to -Wpedantic is not a bad idea.
My experience with third party libraries is that sometimes they use
extensions, probably mostly gcc-isms. Not much to be done in that
case. Of course turning on -pedantic could be done selectively.
It might be worth an experiment of turning off -Wall while turning
on -pedantic to see how big or how little the problem is.
The idea of not going back to the originator (what you call the
parent) is something I developed independently before looking at
your latest code (and mostly I still haven't). Seems like a good
idea.
>
I call it a principle of Lot's wife.
That is yet another reason to not grow blocks above 2x2.
For bigger blocks it does not apply.
Here is an updated version of my "stacking" code. On my test
system (and I don't even know exactly what CPU it has, probably
about 5 years old) this code runs about 30% faster than your 2x2
version, averaged across all patterns and all sizes above the
smallest ones (25x19 and 19x25).
#include <assert.h>
#include <stdlib.h>
typedef unsigned char UC, Color;
typedef size_t Index, Count;
typedef struct { Index x, y; } Point;
extern Count
stack_plus( UC *field, Index w, Index h, Point p0, Color old, Color new ){
Index px = ( assert( p0.x < w ), p0.x );
Index py = ( assert( p0.y < h ), p0.y );
Index x0 = 0;
Index x = px;
Index xm = w-1;
UC *y0 = field;
UC *y = y0 + py*w;
UC *ym = y0 + h*w - w;
UC *s0 = malloc( 8 * sizeof *s0 );
UC *s = s0;
UC *sn = s0 ? s0+8 : s0;
Count r = 0;
if( s0 ) goto START_FOUR;
while( s != s0 ){
switch( *--s & 15 ){
case 0: goto UNDO_START_LEFT;
case 1: goto UNDO_START_RIGHT;
case 2: goto UNDO_START_UP;
case 3: goto UNDO_START_DOWN;
case 4: goto UNDO_LEFT_DOWN;
case 5: goto UNDO_LEFT_LEFT;
case 6: goto UNDO_LEFT_UP;
case 7: goto UNDO_UP_LEFT;
case 8: goto UNDO_UP_UP;
case 9: goto UNDO_UP_RIGHT;
case 10: goto UNDO_RIGHT_UP;
case 11: goto UNDO_RIGHT_RIGHT;
case 12: goto UNDO_RIGHT_DOWN;
case 13: goto UNDO_DOWN_RIGHT;
case 14: goto UNDO_DOWN_DOWN;
case 15: goto UNDO_DOWN_LEFT;
}
START_FOUR:
if( y[x] != old ) continue;
y[x] = new; r++;
if( x < xm && y[x+1] == old ){
x += 1, *s++ = 0; goto START_LEFT; UNDO_START_LEFT:
x -= 1;
}
if( x > x0 && y[x-1] == old ){
x -= 1, *s++ = 1; goto START_RIGHT; UNDO_START_RIGHT:
x += 1;
}
if( y < ym && x[y+w] == old ){
y += w, *s++ = 2; goto START_UP; UNDO_START_UP:
y -= w;
}
if( y > y0 && x[y-w] == old ){
y -= w, *s++ = 3; goto START_DOWN; UNDO_START_DOWN:
y += w;
}
continue;
START_LEFT:
y[x] = new; r++;
if( s == sn ){
Index s_offset = s - s0;
Index n = (sn-s0+1) *3 /2;
UC *new_s0 = realloc( s0, n * sizeof *new_s0 );
if( ! new_s0 ) break;
s0 = new_s0, s = s0 + s_offset, sn = s0 + n;
}
if( x < xm && y[x+1] == old ){
x += 1, *s++ = 5; goto START_LEFT; UNDO_LEFT_LEFT:
x -= 1;
}
if( y > y0 && x[y-w] == old ){
y -= w, *s++ = 4; goto START_DOWN; UNDO_LEFT_DOWN:
y += w;
}
if( y < ym && x[y+w] == old ){
y += w, *s++ = 6; goto START_UP; UNDO_LEFT_UP:
y -= w;
}
continue;
START_UP:
y[x] = new; r++;
if( s == sn ){
Index s_offset = s - s0;
Index n = (sn-s0+1) *3 /2;
UC *new_s0 = realloc( s0, n * sizeof *new_s0 );
if( ! new_s0 ) break;
s0 = new_s0, s = s0 + s_offset, sn = s0 + n;
}
if( x < xm && y[x+1] == old ){
x += 1, *s++ = 7; goto START_LEFT; UNDO_UP_LEFT:
x -= 1;
}
if( x > x0 && y[x-1] == old ){
x -= 1, *s++ = 9; goto START_RIGHT; UNDO_UP_RIGHT:
x += 1;
}
if( y < ym && x[y+w] == old ){
y += w, *s++ = 8; goto START_UP; UNDO_UP_UP:
y -= w;
}
continue;
START_RIGHT:
y[x] = new; r++;
if( s == sn ){
Index s_offset = s - s0;
Index n = (sn-s0+1) *3 /2;
UC *new_s0 = realloc( s0, n * sizeof *new_s0 );
if( ! new_s0 ) break;
s0 = new_s0, s = s0 + s_offset, sn = s0 + n;
}
if( x > x0 && y[x-1] == old ){
x -= 1, *s++ = 11; goto START_RIGHT; UNDO_RIGHT_RIGHT:
x += 1;
}
if( y < ym && x[y+w] == old ){
y += w, *s++ = 10; goto START_UP; UNDO_RIGHT_UP:
y -= w;
}
if( y > y0 && x[y-w] == old ){
y -= w, *s++ = 12; goto START_DOWN; UNDO_RIGHT_DOWN:
y += w;
}
continue;
START_DOWN:
y[x] = new; r++;
if( s == sn ){
Index s_offset = s - s0;
Index n = (sn-s0+1) *3 /2;
UC *new_s0 = realloc( s0, n * sizeof *new_s0 );
if( ! new_s0 ) break;
s0 = new_s0, s = s0 + s_offset, sn = s0 + n;
}
if( x > x0 && y[x-1] == old ){
x -= 1, *s++ = 13; goto START_RIGHT; UNDO_DOWN_RIGHT:
x += 1;
}
if( x < xm && y[x+1] == old ){
x += 1, *s++ = 15; goto START_LEFT; UNDO_DOWN_LEFT:
x -= 1;
}
if( y > y0 && x[y-w] == old ){
y -= w, *s++ = 14; goto START_DOWN; UNDO_DOWN_DOWN:
y += w;
}
continue;
}
return free( s0 ), r;
}