• ### Blog Entries

• entries
12
26
• views
17447

Occasionally related to game development.

## What?

I had a weird dream in which my GDNet rating increased by 1 point (the value was actually correct, too, unlike most of my dreams where numerical values tend to be wrong). I was happy about it, for some reason.

I'm slightly worried.

## DS homebrew

I haven't had this much fun programming in a while. I got a Cyclo DS evolution recently, and started playing with devkitPro and libnds. Here, have some buttons I placed with the stylus.

I plan to write an IRC client, if debugging doesn't turn out to be a complete nightmare.

Ever noticed that .NET-style menus are ugly?

Windows Vista comes with a new style of menus (which allow images, too), and a few updates to the UxTheme API, including the ability to render these themed menus. When the .NET framework was designed, however, this functionality wasn't available; and you can see this clearly by looking at a default MenuStrip.

But ToolStrip allows you to give it a new renderer (via its Renderer property), and you can write a ToolStripRenderer that draws menus using UxTheme with not too much effort.

And that's exactly what I've done, and you can have the source code. Do what you like with it. It only really works with menu bars and context menu bars, because I didn't need it for anything else.

You can apply it in one of two ways, both pretty simple.
Here's some screenshots:
Using Aero (Vista) Theme (120dpi)
Using Luna (XP) Theme (96dpi)
Using Windows Classic Theme (120dpi)

If you do use this, here are some scenarios to test: Starting with Aero on, and turning it on/off and switching into classic mode a few times Starting with Aero off, and turning it on/off and switching into classic mode a few times
In a similar vein, there is also a WindowsVistaRenderer on The Code Project, which draws the sort of dark toolbars you can see in Windows Media Player 11, Windows Photo Gallery, etc.

- MrEvil

## My new found love: XAML

I recently discovered XAML, eXtensible Application Markup Language, when the .NET 3.0 release completely took me by surprise. I didn't even think this stuff would be released on Windows XP!

In an attempt to learn how to use this stuff, I've been writing a tabbed document editor. At the moment it only supports XML documents, and you can't actually... edit them, but the User Interface is what I'm developing here, at the moment.

The XAML source for the window above is:

Class="XmlEdit.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Xml Editor" Height="570" Width="668"
xmlns:clr="clr-namespace:System;assembly=mscorlib"
xmlns:my="clr-namespace:XmlEdit"
xmlns:xml="http://www.w3.org/XML/1998/namespace"

"ApplicationCommands.Close" Executed="AppCloseCommand"/>
"ApplicationCommands.New" Executed="DocNewCommand"/>
"ApplicationCommands.Save" Executed="DocSaveCommand" CanExecute="CanDocumentCommandExecute"/>
"ApplicationCommands.SaveAs" Executed="DocSaveAsCommand" CanExecute="CanDocumentCommandExecute"/>

"my:DocumentCommands.Close" Executed="DocCloseCommand" CanExecute="CanDocumentCommandExecute"/>

"VerticalSplitterStyle">

"documentList"/>

"{Binding Path=Saved}" Value="false">

"DocumentContentTemplate">
"{Binding Path=ContentElement}"/>

"Top">

"_File" >
"ApplicationCommands.New"/>

"ApplicationCommands.Save"/>
"ApplicationCommands.SaveAs"/>
"my:DocumentCommands.Close"/>

"ApplicationCommands.Close"/>

"tabs" ItemsSource="{Binding Source={StaticResource documentList}}"
ContentTemplate="{StaticResource DocumentContentTemplate}"
>

"MiddleClick" Command="my:DocumentCommands.Close"/>

It seems fairly understandable without knowing any XAML. The TabControl is my favourite bit. Its ItemsSource property is bound to a DocumentList, which is derived from ObservableCollection. I then create an instance of this in the Window's ResourceDictionary (&;lt;Window.Resources>), which I can retrieve later in the codebehind file.
That is, you can use data binding with a Collection, and when the collection is updated, the UI is updated too. Also, each of the objects in the collection derives from INotifyPropertyChanged, which allows the UI to re-evaluate the DataTriggers on the template.

Commands are probably the most confusing part. Writing my own commands required writing a static class with RoutedUICommand members. They're then imported by mapping my XmlEdit namespace to the "my:" XML namespace, whereupon I can reference CLR classes and objects. Provided, for some reason, they're not in the same file as the actual codebehind. It doesn't like that at all.

The code to do this is simple... (irrelevant bits left out)

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;

namespace XmlEdit
{
public partial class MainWindow : System.Windows.Window
{
private DocumentList documents;

public MainWindow()
{
InitializeComponent();

//Apparently you can't use the x:Name attribute on elements in a Resource Dictionary,
//so it seems it's not possible to have a member generated in the codebehind... Which
//leaves us with this.
documents = this.Resources["documentList"] as DocumentList;
}

//Commands
public void AppCloseCommand(object sender, ExecutedRoutedEventArgs e)
{
((Window)sender).Close();
}

public void AppNewWindowCommand(object sender, ExecutedRoutedEventArgs e)
{
new MainWindow();
}

public void CanDocumentCommandExecute(object sender, CanExecuteRoutedEventArgs e) {
e.CanExecute = CurrentDocument != null;
}

public void DocSaveCommand(object sender, ExecutedRoutedEventArgs e)
{
IDocument doc = CurrentDocument;
if (doc.Filename != null) {
doc.Save();
} else {
doc.SaveAs();
}
}

//Next problem: how to avoid mingling UI code (display a save dialog)
//and document code...
public void DocSaveAsCommand(object sender, ExecutedRoutedEventArgs e)
{
CurrentDocument.SaveAs();
}

public void DocNewCommand(object sender, ExecutedRoutedEventArgs e) {
IDocument doc = new XmlDocument();
documents.Insert(0, doc);
tabs.SelectedIndex = 0;
}

//Close the current tab. Or, if the event was sent by middle-clicking on a tab, instead just close the tab which sent the event.
public void DocCloseCommand(object sender, ExecutedRoutedEventArgs e)
{
IDocument doc;
if (e.Source is TabItem)
doc = (e.Source as TabItem).Content as IDocument;
else
doc = CurrentDocument;

System.ComponentModel.CancelEventArgs ce = new System.ComponentModel.CancelEventArgs();
doc.Close(ce);
if (!ce.Cancel) {
documents.Remove(doc);
}
}

//...

//Convenience property. Useful, though. Should
//possibly throw an exception if there isn't one...
public IDocument CurrentDocument {
get {
return tabs.SelectedContent as IDocument;
}
}

//I'm sure I was planning to use this
private void WindowLoaded(object sender, EventArgs args) {

}
}
}

It's nice and easy to understand, I think.

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.ComponentModel;
using System.Collections.Specialized;

namespace XmlEdit
{

public interface IDocument: INotifyPropertyChanged
{
string Title {
get;
}

bool Saved {
get;
}

string Filename {
get;
set;
}

System.Windows.UIElement ContentElement {
get;
}

void Close(System.ComponentModel.CancelEventArgs args);
void Save();
void SaveAs();

event EventHandler Modified;
event CancelEventHandler Closing;
event EventHandler Closed;
}

class DocumentList : ObservableCollection
{
public DocumentList() {
}
}
}

I'm using the WPF and WCF extensions for Visual Studio 2005, which are still a preview at the moment. This probably explains why visual studio is using about 350MB of RAM, and managed about 500MB before.

I really want to make a visual studio clone, because it has the coolest interface ever, but it still looks like that would be a lot of work [wink]. This is all certainly more fun than developing with WinForms.

## Boredom

I'm stuck at uni without an Internet connection [depressed] actually, that means I can get some actual work done [wink] I'm currently writing a 2D game for my university project.

Not having Internets causes problems though. I'm drawing all the fonts myself (bitmap fonts [sad]), recording all the sounds myself [grin], and stealing textures/sprites from wherever I can find them because I'm too lazy to make my own. Also, as usual, I got sidetracked. This time I started writing an XML-style data format with syntax that I like better. I call it IML, Inextensible Markup Language. It's not really markup language, but who cares? It'll probably never leave my computer.

Also, I have time to do other things... - say hi to Malcolm, made with a friend due to boredom.

## Chef

I've always wanted to try the language that is Chef. It's the perfect example of an esoteric language. It's humorous, it's difficult to program in, and the resulting program looks funny when completed.

Unfortunately, I haven't been able to find an interpreter that I'd want to use. The Perl Module doesn't interest me, since currently I'd rather stab my eyes out with a fork than use Perl for anything bigger than 50 lines. I'm just not a Perl fan. So at the suggestion of benryves, I am writing my own interpreter. Also, at the suggestion of Seriema, I shall be making it pink. You'll see how in a minute. [grin]

I originally didn't know what language to write this interpreter in. There were two options to begin with, C++ and C#. C++ would be useful since it has a nice parsing library, Boost.Spirit. C#, on the other hand, has easy unicode support, I have a nice development environment for it (Visual studio .NET 2003). But at some point in #gamedev, javascript was mentioned, and all the wonderful memories of using javascript came back to me.

Look at the cool things you can do:

function a(b){
b([2]);
}
a(
function(c){ document.title=c; }
);

//or

var d = (function(a,b,c) { return (a+b+c)/[3] })([1],[2],[3]);

[cool]

So I'm writing my interpreter in javascript. It shall be usable via Windows Script Host or via a web page. The web page option shall indeed be Pink as Seriema suggested.

Note: I wouldn't even be considering doing it in javascript if it wasn't for Venkman for Firefox 1.5, a javascript debugger (which ordinarily only supports 0.8-1.0).

## New journal

Recently a few friends and I purchased a dedicated server, and are now running loads of stuff on it. We've got a counter-strike public server (onfiar.com:27015) running (although we use it for matches sometimes until we can be bothered to sort out two servers).

So I've got a new journal now, which is available at http://asztal.onfiar.com/. The main site aggregates everyone's blogs, and is available at http://onfiar.com/.

I also intend to put stuff up at http://onfiar.com/~asztal -- but it currently it's just a (pink) under construction page.

In other news, I'm considering removing the pink look from my journal, since I've proved to myself that

It can be done
It does look cool

and, unfortunately, it looks awful on www2.gamedev.net. If anyone knows of any ways I can make the pink theme available only on www.gamedev.net, I'd like to know [grin]

## Erm

I appear to have broken the layout at the top with my CSS [sad]

## My System Library

Here is a piece of TriINTERCAL code never seen before. I shall warn you now, it is not pretty [grin]

Without further ado, I present you my TriINTERCAL system library, which is almost complete.

(1009) DO STASH .1 + .2 + .5 + .6
DO .4 DO (1004) NEXT
DO .3 '^.1$.2'~'#0$#29524'
DO .6 "'&"'^"'&"'^"'&.1$.2'~'#0$#29524'"$#29524'~'#0$#29524'"$#59048' ~'#0$#29524'"$#29524'~'#0$#29524'"$#59048'~'#0$#29524'"
PLEASE DO .5 "V!6~#19683'$#1"~#1 DO (1002) NEXT DO .4 (1005) DO (1006) NEXT (1999) DOUBLE OR SINGLE PRECISION OVERFLOW (1002) DO (1001) NEXT (1006) PLEASE FORGET #1 PLEASE DO .5 "V'".6~.6"~#1'$#1"~#1
DO (1003) NEXT
DO .1 DO .2 "!6$#0'~'#9841$#2'"~#59048
DO .2 '^.2$.2'~'#0$#29524'
DO (1004) NEXT
(1003) DO (1001) NEXT
DO REINSTATE (1005)
(1007) PLEASE RETRIEVE .1 + .2 + .5 + .6
DO REMEMBER .4
(1001) DO RESUME .5
(1010) DO STASH .1 + .2 + .4
DO .4 DO .1 '?#59048$.2'~'#0$#29524'
DO (1020) NEXT
DO RETRIEVE .1 + .2 + .4
(1020) DO STASH .2 + .3
DO .2 PLEASE DO (1021) NEXT
(1021) DO FORGET #1
DO .3 "V!1~.2'$#1"~#1 PLEASE DO .1 '^.1$.2'~'#0$#29524' DO (1022) NEXT DO .2 '~'#9841$#1'
DO (1021) NEXT
(1022) DO (1023) NEXT
(1030) DO ABSTAIN FROM (1033)
(1039) DO STASH :1 + .5
DO (1530) NEXT
DO .3 PLEASE DO .5 '#29403$#29403' DO .5 'V"!5~.5'~#2"$#1'~#1
DO (1031) NEXT
(1032) DO (1033) NEXT
DO (1999) NEXT
(1031) DO (1001) NEXT
(1033) DO .4 DO REINSTATE (1032)
DO RETRIEVE :1 + .5
(1060) DO .3'V".1$.2"'~'#0$#29524'
DO RESUME #1
(1070) DO .3'&".1$.2"'~'#0$#29524'
DO RESUME #1
(1080) DO .3'?".1$.2"'~'#0$#29524'
DO RESUME #1
(1090) DO .3'^".1$.2"'~'#0$#29524'
DO RESUME #1
(1091) DO .3'@".1$.2"'~'#0$#29524'
DO RESUME #1
(1509) PLEASE STASH :1 + .1 + .2 + .3 + .4 + .5 + .6
DO .1 PLEASE DO .2 DO (1009) NEXT
DO .5 PLEASE DO .6 DO .1 '#29403$#29403' DO .2 '#29403$#29403'
DO (1009) NEXT
DO .1 PLEASE DO (1503) NEXT
DO .6 DO .2 DO (1009) NEXT
DO .1 DO (1501) NEXT
(1503) DO (1504) NEXT
(1501) DO .2 DO .5 "V.6$.4"~#1 DO (1505) NEXT (1506) DO (1502) NEXT PLEASE DO (1999) NEXT (1505) DO (1001) NEXT (1502) DO :4 DO (1520) NEXT DO :3 PLEASE RETRIEVE :1 + .1 + .2 + .3 + .4 + .5 + .6 DO REINSTATE (1502) DO REINSTATE (1506) PLEASE RESUME #3 (1510) DO STASH :1 + :2 + :4 DO :1 "'?":2~'#29524$#0'"$#59048'~'#0$#29524'"$"'?":2~'#0$#29524'"$#59048'~'#0$#29524'"
DO :2 DO (1509) NEXT
DO :2 PLEASE DO (1509) NEXT
DO RETRIEVE :2 + :4
(1520) PLEASE STASH .3 + .4
DO .3 DO (1525) NEXT
PLEASE DO .4 'V.3$".2~#22143"'~'#0$#29524'
DO .3 PLEASE DO (1525) NEXT
DO :1 "'V.3$".2~#7381"'~'#0$#29524'"
DO RESUME #1
(1525) DO .3 '~'#121$#242' DO RESUME #1 (1530) DO STASH :2 + :3 + .3 + .5 DO :1 DO :2 DO .3 DO (1535) NEXT (1535) PLEASE FORGET #1 DO .5 "@'"^!1~.3'$#7"~#4'$#2"~#10 DO (1531) NEXT PLEASE DO (1500) NEXT DO :1 DO (1500) NEXT DO :1 PLEASE DO (1533) NEXT (1531) DO (1534) NEXT DO (1500) NEXT DO :1 DO FORGET #1 DO (1533) NEXT (1534) PLEASE DO (1001) NEXT DO FORGET #1 (1533) DO FORGET #1 DO .3 '~'#9841$#1'
DO :2 ":2~'#0$#29524'"$"'":2~'#9841$#0'"$#0'~'#9841$#1'" PLEASE DO .5 "V'".3~.3"~#2'$#1"~#1
DO (1532) NEXT
DO (1535) NEXT
(1532) DO (1001) NEXT
PLEASE RETRIEVE :2 + :3 + .3 + .5
DO RESUME #2
DO ABSTAIN FROM (1542)
(1549) PLEASE STASH :1 + :2 + :4 + :5 + .1 + .2 + .5 + .6
DO .1 PLEASE DO .2 '#29403$#29403' DO .5 '#29403$#29403'
DO (1530) NEXT
DO :3 DO .2 PLEASE DO (1530) NEXT
DO :5 DO .1 DO (1530) NEXT
DO :4 PLEASE DO :1 ":3~'#29403$#29403'"$":4~'#29403$#29403'" DO .5 ':1~:1'~#1 DO .5 "V!5~#2'$#1"~#1
DO .2 '#29403$#29403' DO (1530) NEXT DO .6 ':1~:1'~#1 DO .6 "V!6~#2'$#1"~#1
PLEASE DO .5 'V.6$.5'~#1 DO .1 DO .2 DO (1520) NEXT PLEASE DO :2 PLEASE DO .1 DO (1520) NEXT DO (1509) NEXT PLEASE DO .5 "V.5$':4~#1'"~#1
DO :1 DO :2 DO (1509) NEXT
PLEASE DO .5 "V.5$':4~#1'"~#1 PLEASE RETRIEVE :4 (1541) DO :4 DO (1543) NEXT (1542) DO (1544) NEXT PLEASE DO (1999) NEXT (1543) DO (1001) NEXT (1544) DO REINSTATE (1541) PLEASE REINSTATE (1542) PLEASE RETRIEVE :1 + :2 + :5 + .1 + .2 + .5 + .6 DO RESUME #2 (1900) DO STASH .2 + .3 + .5 DO .1 DO .2 PLEASE DO (1901) NEXT (1901) DO FORGET #1 DO %33 .1 'V.1$.2'~'#0$#29524' DO %33 .1 "V!1$".2~#59048"'"~"#0$#29524" DO .2 '~'#9841$#1'
PLEASE DO .5 'V"!2~.2'~#2"$#1'~#1 DO (1902) NEXT DO (1901) NEXT (1902) DO (1001) NEXT DO RETRIEVE .2 + .3 + .5 PLEASE RESUME #2 (1550) DO STASH :1 + :4 + :5 + .5 DO :3 DO .5 'V"':2~:2'~#2"$#1'~#1
DO READ OUT #3000 + .5
DO :4 PLEASE DO (1553) NEXT
(1553) DO FORGET #1
DO .5 '#19683$#0' DO .5 "?!5~#2'$#1"~#1
DO READ OUT #4000 + .5
DO (1552) NEXT
DO :2 ":2~'#0$#29524'"$"'":2~'#9841$#0'"$#
0'~'#9841$#1'" PLEASE DO :4 ":4~'#0$#29524'"$"'":4~'#9841$#0'"$#0'~'#9841$#1'"
DO (1553) NEXT
(1552) DO (1001) NEXT
DO :5 "'?":1~'#29524$#0'"$":2~'#29524$#0'"' ~'#0$#29524'"$"'?":1~'#0$#29524'"$":2~'#0$
#29524'"'~'#0$#29524'" DO .5 '&"':2~:5'~'"'^"'?:5~:5' ~'#29524$#0'"$#19683'~'#0$#29524'"
$"'?:5~:5'~'#0$#29524'"'
"$"':5~:5'~#1"'~#1 DO .5 "?!5~#2'$#1"~#1
DO NOTE THAT THE ABOVE THREE LINES DO NOT WORK
DO READ OUT #1000 + .5
DO (1554) NEXT
DO :5 DO (1510) NEXT
DO :3 "'^":4~'#29524$#0'"$":5~'#29524$#0'"' ~'#0$#29524'"$"'^":4~'#0$#29524'"$":5~'#0$
#29524'"'~'#0$#29524'" DO (1556) NEXT (1554) PLEASE DO (1001) NEXT (1555) DO FORGET #1 DO .5 '?":4~#2"$#1'~#1
DO READ OUT #2000 + .5
DO (1551) NEXT
DO :2 ":2~'#0$#29523'"$":2~'#29524$#0'" DO :4 ":4~'#0$#29523'"$":4~'#29524$#0'"
(1551) DO (1001) NEXT
PLEASE RETRIEVE :1 + :4 + :5 + .5

I have yet to write routine (1550), 10-trit (roughly 32-bit) division. Once I have implement this I can go on to write (1050) and (1910). The problem I am encountering is that of 10-trit comparison.

The (1550) routine works by repeatedly shifting the denominator leftwards by one trit (thus multiplying by 3), and subtracting the denominator from the numerator. (In the case of the denominator being zero, we set the overflow bit (.4), and return. Let us call the denominator y, and the numerator x, so that we are calculating x/y. Let the quotient be q, and the remainder r. We repeatedly subtract y from x, until x
If it takes us two subtractions to do this, we set the current trit of the quotient to 2. If it takes us only one subtraction, we set the current trit to 1, otherwise we set it to 0. Let us also have a number b, representing the current trit that we are twiddling. This starts at 2, and we use the V (or) mechanism to OR it with the current quotient, thus setting that bit, then we shift b leftwards by one trit. We repeat until b is 0, i.e. we have shifted the 2 trit off the edge.

This is clearly a constant time operation. The above algorithm is not, however, perfected. I haven't determined a way to set the current bit of the quotient to 2 or 1 or 0 depending on the amount of times we had to subtract y from x. I suspect we may have to either:

Have two variables which contain the bit to OR into the quotient.

I hope you understood all that, and I also hope someone knows how to test for 10-trit greater-than in TriINTERCAL. [grin]

At the moment, I think it should look something like this:

DO :5 "'?":1~'#29524$#0'"$":2~'#29524$#0'"' ~'#0$#29524'"$"'?":1~'#0$#29524'"$":2~'#0$
#29524'"'~'#0$#29524'" DO .5 '&"':2~:5'~'"'?"'?:5~:5' ~'#29524$#0'"$#19683'~'#0$#29524'"
$"'?:5~:5'~'#0$#29524'"'
"$"':5~:5'~#1"'~#1 DO .5 "?!5~#2'$#1"~#1

## Befunge!

Ok, so I am currently posting without a mouse. This sucks. Especially when you try to use Firefox. The thought for the day is,

[grin]Befunge![grin]

I'm currently developing a command-line 3D befunge interpreter, which will hopefully be cross-platform. I am attempting to do this in C++, with quite some success.

My interpreter doesn't interpret befunge-93 as such, it interprets a fungeoid which is quite similar to befunge-93. My dialect uses 32-bit (int) values for the code/data and stack values.

I also include a stack stack, which is (as the name suggests) a stack of stacks. { pushes a stack, } pops a stack. The usual befunge-93 semantics apply to most functions, except g and p. g and p currently pop 3 values from the stack, since it is a 3D version of befunge.

The interpreter will also include native threads and TCP sockets (which will be swapped in to be manipulated via '~','&',',' and '.' as usual - in addition, file manipulation may be included, although then the language might become vaguely useful [wink].

Once I have written all this, I plan to write a befunge IRC client/server. It shall be great.

My progress so far:
I have implemented a befunge-93 interpreter. I'm having problems with the threads and lifetime issues with sockets [sad]

## Replacing the logon screen

I just discovered how amazingly fun it is to replace the Windows NT logon screen. If you like Win32, that is.

The logon screen is called the GINA DLL (Graphical Identification and Authentication), and is loaded at system startup by Winlogon.exe. The purpose of the GINA is to display identification dialogs and perform authentication using LogonUserEx and friends.

The cool thing about the GINA is that it runs as SYSTEM, inside a core Windows Process, so there's a real good chance you can screw something up. My favourite Blue Screen of Death has the following text:

That made my day [lol]. On a more serious note, I learnt a lot about Win32 security - it is, of course, essential that password information is not leaked. Every time a password is no longer needed, it must be zeroed out in case it is later retrieved (I wonder how many holes my GINA has). I don't understand this actually, since after reading Inside Windows NT I thought the kernel zeroed out all pages when they were re-used by another process. But anyway..

There is also excellent bug potential. For example, if you fail to pass the environment block to the CreateProcessAsUser function, the user's shell won't draw any of its windows properly. I had fun figuring that one out...

You can modify the behaviour to some extent - it's possible to give the logged on user whatever access rights you like.

I originally had plans to use Direct3D in my logon screen, until I found out that you're not supposed to use COM inside core Windows processes [sad].

The downside of all this is that it requires two windows boxes or a dual boot configuration. Or, if you are insane, you can deploy the custom GINA on your development machine. Just make sure you have your windows CD handy or can boot into safe mode. [wink]

I'll probably keep this journal updated with my progress on the project.

I think I'm the only GDNet+ user without an avatar.. [looksaround] [/edit]

## Don't do this

Imagine you have a C++ class 'program', which takes a reference to a stack in its constructor.

template
struct program{
typedef T value_type;
stack& stk;

program(stack& stk): stk(stk)
{}

void operator()(){}
};

That's all very well, until you decide to have the stack as a member variable, and it changes to this.

template
struct program{
typedef T value_type;
stack stk;

program(): stk(stk)
{}

void operator()(){}
};

Obviously I should have got rid of the stk(stk) initialiser, but this is a really simpilified example; in my code the constructor code was in a different file and there were about 15 initialisers.

Your stk is now being initialised by itself. On my system, which was g++ 3.3.3 on cygwin, it went into an infinite loop where it eventually ran out of memory.

My question is, shouldn't it have at least warned me about that?