Am I finally surpised or just about to pass out?

Ok, now I really know that I’ve got to dig up a copy of the C++ standards (both 1998 and 2003) and run a personal sanity check or C++ has finally succeeded in shocking me. Tested each of these with g++ 4.2.1 using the -std=c++98 -pedantic switches for the sake of quickness.

    int f=true;
bool b=15; // 15 is demoted to 1
enum foo_t { ONE,TWO };
enum foo_t spam=ONE; // ok
enum foo_t ham=false; // error
enum foo_t eggs=1; // error

In C the enum would be little better then making a pair of preprocessor defines for 0 and 1 and ‘foo_t’ being much like an equivalent to a typedef to one of the common integer types. In C++ enums create new types, that’s nice because it actually forces you to use one of the enum values, making the last line of the example (assigning a foo_t an int) becomes an error in C++ rather then (likely) a typo in C.

That makes good sense to me and I like it, ok.

Most C implementations that I’ve seen that have a stdbool.h usually settles things as defining bool as an int either via reliance on typedef or the preprocessor, then defines true/false as 1/0. So there is really nothing to enforce a bool to equal anything else in common C, although I’ve never seen an undesired result… But in C++, bool is done as a fundamental type…. not an afterthought. So the thing I don’t understand is why restrict newly created enumerations to there sane values, shooting off a compiler error if something odd happens. But allow the built in booleans to be ‘almost’ automatically converted like regular numerics? (apparently similar to the usual promotion/demotion rules)

bool isSomething = false; // becomes 0
isSomething++; // becomes 1
isSomething -= 500; // strangely becomes 1
isSomething--; // is an error using this operator
isSomething = isSomething -1; // becomes 0

I find it rather odd that things seem to work this way, the only logical reason I could see for it is compatibility with those in a ‘#define true 1’ world. Personally I don’t have a problem with it, I just find it odd. Maybe if I nabbed a copy of the C++ standard it would make more sense. I’m familiar enough with reading the C standard (and enjoy it) but I’ve never managed to get a copy of the relevant C++ standards :. Heh, then again until recent months I haven’t really touched C++ in ages… But it has been encroaching on things I normally use C or Perl for doing.

Or maybe I just need some damn __SLEEP__

the nights antics

I was rather happy to see that SourceForges SVN services were back up to a decent speed, other wise I probably would’ve gone to bed instead of getting back to work :

I managed to finish the work on the project file, I had inhaled the qmake manual before dinner ;-). I knew exactly what I wanted, test works all been done in a ‘one lump sum’ directory… Which is the style that I really hate, to much crap to visually grep through when looking for parts of the project.

The build format that I desire is basically like:

Makefile -> top level, non recursive make
doc/ -> documentation files
dist/ -> files ready to install (all done)
obj/ -> object files and crap from moc / building docs, etc
src/ -> source code files
src/module/ -> source code files for module

Which is basically what I’ve setup, maybe I’m just spoiled by the layout of FreeBSDs source tree and build system… hehe.

I was quite happy to find that as usual, Qt makes life easier not harder xD. It only took the fine (if short) manual and a little bit of trial time to get more or less what I wanted out of it, all the better! Without having to worry about a recursive trail of makefiles. When it comes to recursive makes, I have no problem with the concept, I just don’t care much for it.

I figured that if I couldn’t get what I wanted out of qmakes project files that I would have to do things manually. I don’t really have a problem with hand crafting makefiles but I really prefer not to have to maintain them, let along risk leaving something behind that needs a Bachelors of GNU Makeology to understand fully.

I did manage to get one module (essentially) imported into the SVN tonight and I’ve almost got another ready to go in. But before I commit it, I want to get the things refresh() slot sorted out. To do that, I just need to clear the m/v I guess but that can wait until tomorrow’ish.

As I often have said, laptops make poor pillows !

There’s about 5 more modules to import, as soon as they are adapted and ready to roll that is. Right now I’m in advantageous territory code wise but as usually, my working environment is, uhh… “Hostile” to say the least to productivity.

Maybe if anyone in this fuckin’ family knew an ounce of computers, let along programming, the bastards would let me work in peace rather then in pieces !!!!!!!

misc thoughts

Well some progress, aside from spending an embarrassing amount of time trying to find a problem starring me right in the face shouting “this is wrong you moron!”, I suppose exhaustion can do that…

To be perfectly honest I think one of my biggest problems is my multi-lingual nature when it comes to programming. In the past couple days, I’ve used Bourne (with best buddies SED & AWK of course), Perl, Ruby, PHP, and C++ for various tasks.

In a large way, a language is just pretty much a language to me, a standard syntax, types, and subroutines if you will. Generally I think about solving problems in a way that doesn’t really connect to a specific language. Sure I tend to write and think in a language of the moment but at the end of the day, the implementation is the language specific part — not the solution.

When it’s something that takes me a bit of thought, I usually write it done in a form of pseudo code that relates to how I read code.

Then start thinking about that, i.e. it’s behavior: I dislike needing debugging aids when a brain will suffice. Then I start thinking about how to implement it, which often tends to lead to what language I’ll be using if not already knee deep in it.

For example, when it comes to regular expressions I very, very greatly prefer Perl and Ruby for such tasks. Python in particular has always felt (to me) a bit chunky at regexes compared to Perl but to each their own methods. Heck, a lot of times a scratch and run Perl script is my way of testing regular expressions for things.

Tonight I needed to figure out how to process a programs output, I quickly found the QProcess class to be increasingly *annoying* so I threw it out in favor of popen() and the usual methods — works like a charm. Then took a quick sample of the programs output, wrote a perl script to handle the operations upon it that was needed.

Then used the QRegExp and QString classes to implement the program using those regular expressions: skipping the compile time frustrations and indexing issues. Then proceeded to expand it into something able to meet my required behavior, after checking enough scenarios to validate it (to me). Then tested that to make sure it still behaved properly and moved on to using it to work on the next problem.

I’ve been using C++ a lot lately, really odd because I mostly quit using it after picking up C and Ruby a couple years ago lol.

0400, time for bed… but first it’s snack time!!!

believe it or not but a few hours of working on the computer has a few side effects ^_^

Recent activities.

Havn’t had a lot of spare time lately :

Survived my 20th birthday on the 20th, makes me wonder if I’m starting to get old in my own way lol.

My brother called and wished me a happy birthday, was good to talk with him even if I had to put up with a ‘lecture’ 8=). I know the old axim is “those who can’t do, teach” but in my families case it is lecture >_>.

Night before my birthday I managed to polish off one of my favorite burgers from Ruby Tuesdays. I remember the first time I had one, hehe a few years back I was the only guy involved in a project. So the girls had to throw a birthday party and what else but The Ultimate Colossal Burger xD

They always did know how to throw a party lol.

Ma also made 2lbs of Chili, so I’ve been feasting on that for the past couple days, hmm now that I think of it.. A little chili would hit the spot about now ;).

I spent most of my birthday eating, sleeping, and coding — three good things, especially since sleep is a premium for me +S. I ain’t done much of anything in C++ in about 3 years, sad considering November will be my fourth anniversary. But I’ve really been enjoying the C++/Qt4 work of late, even better I’ve got suitable development environments on my laptop and desktop. Lunch was a trip to the best all you can eat joint in town, so that went well hehe.

Still, it’s all overshadowed by one thing… But I guess that’s a different subject.

I’ve managed to get a bit of training in this weekend, been concentrating on the fundamentals of room clearing for Jonsi’s training. One nice thing about teaching it, I’ve been doing it enough in the virtual world, that I parts of it flow into the real world lol.

Ok, so is it that bad if you tend to stack on doors and button-hook entries ? haha

Started work today on a diagram for a new swat4 map, The [SAS] Killhouse Redux. I’ve got over 25 rooms and two floors with concepts for adding another wing on the first floor. What I like the most about the design, it’s trivial to build it in bits and pieces. Level 1As first wing, then the other wing or Level 2A, etc. My original “dream” for the ultimate training facility included like a 5-6 floor shooting house but no map maker got into the project.

The only big problem is me and the Unreal Editor used mix like water and oil. I should be happy though, as crappy as SwatEd is it really is less bothersome then the UnrealEd build shipped with Raven Shield. Although I’m more used to the Rvs build… At least the S4 one doesn’t crash so often!

I can do almost anything I set my mind to, it’s just a matter of time. Tomorrow I need to inhale one of the tutorials and set to work on more of the map. The main problem atm is adjusting the objectives, although I reckon I could always make a room in the middle of no where full of tangos lol. The old [SAS] Killhouse in RvS that we used to use before I even got here, had a lone tango hidden behind boxes. But that was more so because of issues with the game design, Swat4 is a little less, ehh irksome.

Today I also got some time on the SWAT4:TSS server for the first time in a good while, I really miss that game lol. The only bad thing I can say, is the MP5s don’t support full auto. I’d rather have a trusty MP5N but hey, the devs had to make it more ‘balanced’ :. The UMP.45 fires at about 300 RPM on their own scale and on full auto, while the MP5 is limited to three round bursts as respective alternatives to semi automatic.

I really prefer full auto because I can control the bursts. In RvS, I often like to use the MP5/10A2 because the way it was implemented. You can’t hit shit past about 30 metres and if you fire more then 2 rounds at a time, you won’t (consistantly) hit shit to start with ! The FAMAS G2 also has such a high rate of fire, that it’s great fun to put on full auto and try to fire one round from it per trigger pull.

SWAT4 has one of the worst simulations of ballistics I’ve ever seen but, Rvs has good shooting but the worlds most unreal physics.

Tomorrows plans, map making and training ops. With how long it’s been since I’ve really played SWAT4, I think I should take some drill time to work on my usual reflexive plan.

3-round burst to centre mass then follow up with a double tap or another burst to the noggin.

Me, I fire a lot of rounds per kill — because I keep firing till the f****er goes down. The advantage of video games is, once they die they start to fall over dead (realistically or not). The disadvantage is unlike the real world, getting shot doesn’t have much effect on the enemy. At the best you might jar their shots (rvs) or stun them briefly (swat4) for another follow up shot.

What I really would love to do some day, is set up sensors on the monitor and a laser pointer on a model weapon. And have the sensors on the screen detect the movements of the laser beam across their own beams and use that to generate mouse movement-input for the operating system.

That would make aiming a lot more reflexive then a mouse lol.

Does Python or PyQt3 have a pox on C++?

This is illogical as I’ve seen Python get.

Terry@dixie$ cd code/C++/src/qsm                                           0:11
Terry@dixie$ python 0:11
Python 2.5.2 (r252:60911, Apr 17 2008, 16:34:02)
[GCC 3.4.6 [FreeBSD] 20060305] on freebsd6
Type "help", "copyright", "credits" or "license" for more information.
>>> from qt import *
>>> QDialog
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'QDialog' is not defined
>>>
Terry@dixie$ cd $HOME 0:11
Terry@dixie$ python 0:11
Python 2.5.2 (r252:60911, Apr 17 2008, 16:34:02)
[GCC 3.4.6 [FreeBSD] 20060305] on freebsd6
Type "help", "copyright", "credits" or "license" for more information.
>>> from qt import *
>>> QDialog
<class 'qt.QDialog'>
>>>

Maybe there is a reason for this and I’ve just got to much of a headache from today to notice it, but WTF man? lol. It’s almost as if Python has a pox on running a script in that directory :

I wanted to test an idea for a dialog quickly, so I started a new python script. Only to have NameError’s whenever trying to reference a member of the qt module. So i copied over one of the py-qt3 example programs that came pre-installed and tried that, same barfing results.

Then I tried interactively with python, no go — changed directories to home and tried both, and they fucking work !!!!

I don’t know whether I should laugh out loud or start hex editing maliciously lol.

Musings about the new GCC

GCC 4.3.0 exposes a kernel bug

Interesting discussion,

I know FreeBSD 7 is moving to GCC4 for the system compiler, iirc 7.0-Release comes with 4.2.x. I have GCC 4.3 installed on this laptop but my primary reason for it is that I wanted to try GCJ, the GNU Compiler for Java :-).

I can’t say the same about Linux distros but I’d expect FreeBSD to always make sure the systems compiler won’t have problems with a build world/kernel cycle.

I’ve only used GCCs 3.x.x C and C++ compilers but I’m not partial, all I expect from a compiler is sufficient standards compliance to the current standards. GCC 3.4.6 might not be perfect but hey, it beats Microsoft’s C Compiler hands down last I tried it :-).

I used to collect some types of software, text editors, terminal emulators, shells, window managers, and sometimes even office suites but I never took to collecting C Compilers. Largely because I don’t want to sit and wait to compile one more often then needed haha.

Beware of Pythons

One sad side effect of using Python so much the past few months..

I actually had to invoke GDB’s ‘help’ command when debugging some C code tonight :

I know several languages but I tend to do things in “the language of the moment”, if I’m working on some thing in C, most of what I do on the side will usually end up in C. Like wise if its a project in Ruby, ruby scripts start filling up lol.

Maybe my brain could use an extra 256K of memory?

rf.c revisited

Got bored, so I revisited an old program I wrote like last year. One of the very first ones I set out to write in C in fact. I admit there is no practical need for this program haha. The only reason I wrote it is that I found it some one annoying that the cat program was made to concatenate files and print them to stdout. But is all so often just used to print out a lone file when less -F does the same thing. For the fun of it I basically added the ability to mimic the head and tail commands with an implicit number of lines to print (e.g. like head -n / tail -n ) while still keeping to the basic function of outputing a lone file, later I made it handle multiple files just for fun.

I was remembering today the sfalloc() macro I had defined early on. Some thing like

#define sfalloc( _type, _ptr ) 
(_type *)malloc( sizeof(_ptr) )

The main point of it was to ensure I wrote sizeof(foo) instead of sizeof(int) or some thing. And to get it to compile with a C++ compiler. I was thinking about making a new version of it for one of my header files that would use the cast only if __cplusplus was defined or better yet the new operator instead for use in code I would want to be compatible with both C and C++ but why bother for such a small program? Althouhg it would be a good spot to test it out in if I did hehe. Besides MSVC++ is a pain in the ass any way for compiling C99 code (imho).

My favorite non standard extensions to the C standard library on BSD and GNU systems is deffo err(), errx(), warn(), warnx(), and related routines in err.h namely because they are major time savers imho. Since a unix like system is assumed unistd is included and getopt(3) used for parsing argv rather then doing it manually.

I didn’t use the various linked list macros provided by BSD boxes because I wanted to avoid them, in case I ever decided to build the app on Windows or DOS. It also was the first time I ever used a linked list in a C program so I wanted to give it a go hehe. I’m really glad I did to because it was a really good excuse to learn how to use the GNU Debugger at the time 😉

One of the changes I made today was ensuring it would compile fine without assuming a C99 environment, I also ran it by gcc42 with -std=c89 -ansi and -pedantic-errors in the hopes of catching any thing I might’ve visually missed.

the ‘final’ version of the old program

/*-
* Copyright (C) 2007
* [my name ]. All rights reserved.
*
* permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/


#if __STDC_VERSION__ >= 199901L
/* inline functions were added in C99 */
#else
#define inline /* protect me */
#endif

#define MALLOC_FAILED "Unable to initialize memory at __LINE__ n"

/* magic number for debugging read_bottom() and clean_up() */
#define NOMEM ((struct lnpos *)0xDEADBEEF)

#include <err.h>
#include <errno.h>
#include <limits.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

/* For storing end of line characters */
typedef struct lnpos {
long eol;
struct lnpos *next;
struct lnpos *prev;
} LNPOS;


static inline FILE *open_file( char * );
static inline void read_all( FILE *, int );
static void read_top( FILE *, int );
static void read_bottom( FILE *, int );
static inline void clean_up( LNPOS * );
static inline void be_verbose( char * );
static inline void usage( void );


static const char *this_progname;


/*
* rf - read file to standard out v2.0 -- see changes.log for details
*/
int
main( int argc, char *argv[] ) {

char *errp;
int b_flag = 0, s_flag = 0, t_flag = 0, v_flag = 0;
int ch, f, lncnt = 0;
FILE *fp;


setlocale( LC_ALL, "" );
this_progname = argv[0];

while ( (ch = getopt( argc, argv, "b:st:v" )) != -1 ) {
switch ( ch ) {
case 'b':
/* Mimic tail(1) -n */
b_flag++;
lncnt = strtol( optarg, &errp, 10 );
if ( *errp || lncnt <= 0 ) {
errx( EXIT_FAILURE,
"Improper line count -- %sn", optarg );
}
break;
case 's':
/* Suppress -v when given multiple files. */
s_flag++;
v_flag = 0;
break;
case 't':
/* Mimic head(1) -n */
t_flag++;
lncnt = strtol( optarg, &errp, 10 );
if ( *errp || lncnt <= 0 ) {
errx( EXIT_FAILURE,
"Improper line count -- %sn", optarg );
}
break;
case 'v':
/* Append file names -- be_verbose() */
v_flag++;
break;
case '?':
default:
usage();
/* NOTREACHED */
}
}
argc -= optind;
argv += optind;

if ( argc < 1 ) {
usage();
}

/* Handle multiple files */
for ( f = 0; f < argc; f++ ) {
fp = open_file( argv[f] );

if ( (!t_flag) && (!b_flag) ) {
read_all( fp, lncnt );
} else if ( t_flag ) {
read_top( fp, lncnt );
} else if ( b_flag ) {
read_bottom( fp, lncnt );
} else {
usage();
/* NOTREACHED */
}

if ( (v_flag != 0) || (argc > 1) ) {
/* Don't suppress if not set */
if ( s_flag == 0 ) {
be_verbose( argv[f] );
v_flag++;
} else {
v_flag = 0;
}
}

fclose( fp );
}

return EXIT_SUCCESS;
}


/* Simple fopen wrapper to keep the if...else if...else blockage from getting
* ugly. Since doing other wise would defeat the purpose of it in this program.
* open_file() halts the program if fopen failed.
*/
static inline FILE *
open_file( char *arg ) {

FILE *fto;

fto = fopen( arg, "r" );
if ( fto == NULL ) {
errx( EXIT_FAILURE, "File can not be opened or"
" does not exist -- %sn", arg );
}

return fto;
}


/*
* print out an open file to standard output
*/
static inline void
read_all( FILE *fp, int lncnt ) {

while ( (lncnt = fgetc( fp )) != EOF ) {
printf( "%c", lncnt );
}
}

/*
* Read n lines from the top of the file.
*/
static void
read_top( FILE *fp, int lncnt ) {

int c = 0;
int f = 0;

while ( (c < lncnt) && (f != EOF ) ) {
f = fgetc( fp );
printf( "%c", f );
if ( f == 'n') {
c++;
}
}
}


/*
* Read n lines from the bottom of the file
*/
static void
read_bottom( FILE *fp, int lncnt ) {

int fin = 0, i;
long int eolnum = 0;
long int where;
struct lnpos *cur = NULL;
struct lnpos *root = NULL;
struct lnpos *last = NULL;

/* initiate the linked list */

root = malloc( sizeof(root) );
root->eol=0;
if ( root == NULL ) {
err( EXIT_FAILURE, MALLOC_FAILED );
}
root->next = NOMEM;
root->prev = NOMEM;
cur = root;

cur->next = malloc( sizeof(cur->next) );
cur->next->eol = 0;
if ( cur->next == NULL ) {
err( EXIT_FAILURE, MALLOC_FAILED );
}
cur->next->prev = cur;
cur->next->next = NOMEM;
cur = cur->next;


/*
* read the file, count every end of line and store them in a new
* member of our linked list.
*/
while ( (fin = fgetc( fp )) != EOF ) {
if ( fin == 'n' ) {
eolnum++;
cur->eol = ftell( fp );
cur->next = malloc( sizeof(cur->next) );
cur->next->eol = 0;
if ( cur->next == NULL ) {
err( EXIT_FAILURE, MALLOC_FAILED );
}
cur->next->prev = cur;
cur->next->next = NOMEM;
cur = cur->next;
}
}

/* double check last nodes prev is up to date before marking the end */

cur->next = malloc( sizeof(cur->next) );
cur->next->eol = 0;
if ( cur->next == NULL ) {
err( EXIT_FAILURE, MALLOC_FAILED );
}
cur->next->prev = cur;
cur->next->next = NOMEM;
cur = cur->next;
last = cur;

/* print out the rest of file from the given offset. */
for ( i = 0; i < lncnt; ) {
if ( cur->prev != NOMEM ) {
if ( cur->eol ) {
i++;
}
cur = cur->prev;
}
}


where = fseek( fp, cur->eol, SEEK_SET );
if ( where != 0 ) {
err( EXIT_FAILURE, "Could not seek through the filen" );
}
read_all( fp, lncnt );
clean_up( root );

}

static inline void
clean_up( LNPOS *root ) {

/* Free linked lists memory */
struct lnpos *cur = root;
while ( cur->next != NOMEM ) {
cur = cur->next;
if ( cur->prev != NOMEM ) {
free( cur->prev );
cur->prev = NOMEM;
}
}
free( cur ); /* free the end node */
}

static inline void
be_verbose( char *fname ) {

printf( "n==> %s <==n", fname );
}

static inline void
usage( void ) {

fprintf( stderr, "usage: %s [-t count | -b count] "
"[-v] [file ...]n", this_progname );
exit( EXIT_FAILURE );
}

The simple makefile compiles it:

gcc -Wall -Wpointer-arith -Wcast-qual -Wcast-align -Wconversion
-Waggregate-return -Wstrict-prototypes -Wmissing-prototypes
-Wmissing-declarations -Wredundant-decls -Winline -Wnested-externs
-std=c99 -march=i686

and Makefile.optimize adds the -fforce-mem -fforce-addr -finline-functions -fstrength-reduce -floop-optimize -O3 options for when testing is done, program works fine. FreeBSD’s lint implementation also doesn’t spew any serious messages.

GCC42

I was installing a program last night on my laptop that needed several GNUStep stuff, so I found out the hardway that it needed GCC v4.2.x’s Objective C compiler…

It took maybe 3 1/2 to 4++ hours to build lang/gcc42 but I suppose it’s a good thing. I always wanted to give it a test drive and it seems to have included the Fortran and Java (gcj) compilers with it.

The only good things I can say is one of my C programs built fine with the C Compiler (/usr/local/bin/gcc42) and I got to thumb through the source code in /usr/ports/lang/work/gcc-*/ while I waited. The parts I saw were quite well documented to and a pleasure to read.

One nice thing I suppose, a successful build of a compiler collection is probably a good stress-test for my laptops hardware :

Wasting time with the Euclidean Algorithm

The other night, I was very bored so… When I remembered reading about the Euclidean Algorithm on Wikipedia, which is a method of finding the greatest common denominator (gcd). I fed several implementations through ye ol’time(1) to get a rough idea of what differences they made.

At first I did it in Ruby and C for comparison, then I recompiled the *.c files with maximum optimization. Tonight I added a set of Java and Python files to the setup, I’ll probably include Bourne Shell and Perl later for fun.

For any one interested,

C // no optimization
./iteration 0.00s user 0.00s system 50% cpu 0.003 total
./recursion 0.00s user 0.00s system 66% cpu 0.002 total
./original 0.00s user 0.00s system 57% cpu 0.003 total
Ruby
./iteration.rb 0.01s user 0.00s system 59% cpu 0.014 total
./recursion.rb 0.00s user 0.00s system 79% cpu 0.010 total
./original.rb 0.00s user 0.01s system 75% cpu 0.010 total
C // optimized, -O3
./iteration-o 0.00s user 0.00s system 48% cpu 0.003 total
./recursion-o 0.00s user 0.00s system 32% cpu 0.005 total
./original-o 0.00s user 0.00s system 37% cpu 0.004 total
Java
java EuclideanIteration 0.39s user 0.38s system 66% cpu 1.165 total
java EuclideanRecursion 0.48s user 0.30s system 72% cpu 1.066 total
java EuclideanOriginal 0.36s user 0.42s system 67% cpu 1.155 total
Python
./iteration.py 0.01s user 0.01s system 59% cpu 0.034 total
./recursion.py 0.01s user 0.01s system 65% cpu 0.032 total
./original.py 0.01s user 0.01s system 65% cpu 0.031 total

done with:

ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-freebsd6]
gcc version 3.4.6 [FreeBSD] 20060305
javac 1.5.0
Python 2.5.1

The C versions were the same sources but compiled with -O3 for the optimized
version.

I’ve assigned each outcome a score, 3 for what I feel is fastest, 2 for the intermediate (often close) and 1 for the worst and totalled it:

method  C RB C(-O3) Java Python Total
iteration 2 1 3 2 2 10
recursion 3 2 2 1 1 9
original 1 3 1 3 3 11

And the code, which I tried to keep similar. Also the gcd()/mygcd() routines were always implemented as a function because of the recursive version in the tests.

#include <stdio.h>

#define A 1071
#define B 1029

int
mygcd( int a, int b ) {
int t = 0;
while ( b != 0 ) {
t = b;
b = a % b;
a = t;
}
return a;
}

int
main(void) {
mygcd(A, B);
return 0;
}


#include <stdio.h>

#define A 1071
#define B 1029

int
mygcd( int a, int b ) {
if ( b == 0 ) {
return a;
} else {
return mygcd( b, a%b );
}
}

int
main(void) {
mygcd(A, B);
return 0;
}


#include <stdio.h>
#define A 1071
#define B 1029


int
mygcd( int a, int b ) {
while ( b != 0 ) {
if ( a > b ) {
a = a-b;
} else {
b = b-a;
}
}
return a;
}

int
main(void) {
mygcd(A, B);
return 0;
}

#!/usr/local/bin/ruby -w

def gcd(a, b)
while b != 0
t = b
b = a % b
a = t
end
return a

gcd( 1071, 1029 )
#!/usr/local/bin/ruby -w

def gcd(a,b)
if b == 0
return a
else
return gcd(b, a % b )
end
end

gcd( 1071, 1029 )
#!/usr/local/bin/ruby -w

def gcd( a, b )
while b != 0
if a > b
a = a - b
else
b = b - a
end
end
return a
end

gcd( 1071, 1029 )

class EuclideanIteration {
static final int A = 1071;
static final int B = 1029;

public static int
mygcd( int a, int b ) {
int t = 0;
while ( b != 0 ) {
t = b;
b = a % b;
a = t;
}
return a;
}

public static void
main( String[] args ) {
mygcd(A, B);
}
}



class EuclideanRecursion {
static final int A = 1071;
static final int B = 1029;

public static int
mygcd( int a, int b ) {
if ( b == 0 ) {
return a;
} else {
return mygcd( b, a%b );
}
}


public static void
main( String[] args ) {
mygcd(A, B);
}
}


class EuclideanOriginal {
static final int A = 1071;
static final int B = 1029;

public static int
mygcd( int a, int b ) {
while ( b != 0 ) {
if ( a > b ) {
a = a-b;
} else {
b = b-a;
}
}
return a;
}


public static void
main( String[] args ) {
mygcd(A, B);
}
}

#!/usr/local/bin/python

def mygcd(a, b):
while b != 0:
t = b
b = a % b
a = t
return a


mygcd( 1071, 1029 )
#!/usr/local/bin/python

def mygcd( a, b ):
if b == 0:
return a
else:
return mygcd( b, a %b )


mygcd( 1071, 1029 )
#!/usr/local/bin/python

def mygcd( a, b ):
while b != 0:
if a > b:
a = a-b
else:
b = b-a
return a


mygcd( 1071, 1029 )