Navigate

· Home page

· Bio

· Projects

· Tips & Tricks

· Programming

    · C/C++

    · Java

    · Bash

    · Python

    · SQL

    · Prolog

    · Haskell

    · Matlab

    · MIPS Assembly

    · VB/VBA

· More Links

· Colleagues

· Weekly Schedule

· Research


Trent Apted's Photo




Trent Apted's Programming

See also Trent's Random Coding Projects. It's a Trac Wiki and is much easier to manage than this mess.

Last updated 2004-09-02

I have been fluent in all the programming languages on the left at some stage in my life. I now mainly use C/C++ (and Bash, SQL, Prolog). If I can be bothered I'll say something about them and my experience. For now, this page is a stub. That's just another way of saying 'under construction' without low-resolution animated GIFs of a construction worker with a shovel.

C / C++

Did you know...

The (quite common) use of the "static" storage class specifier in C to indicate that a particular declaration is local to a translation unit (i.e. isn't given external linkage so that it can be used in other files), is deprecated in C++? The accepted alternative is to use unnamed namespaces (gcc calls them anonymous namespaces) instead. If you don't know what these are:

	namespace {
        	int f(int);
        }

is roughly equivalent to going

	namespace $$$ {
        	int f(int);
        }
        using namespace $$$;

and acheives roughly the same effect as

	static int f(int);

However, whether the compiler treats them the same is not known to me. Although a good sign is that the gcc docs are careful about identifying optimisations applicable to functions that are "local to a translation unit" (i.e. rather than "functions declared static").

Mind you, C-Style casts are deprecated too, but I don't see those going away any time soon. Many programmers I've talked to don't even know what a 'reinterpret_cast' is. If you are one of these people, make sure you also know what 'static_cast' and 'const_cast' are. There is also 'dynamic_cast', which is in a slightly different category, but also better known because it's most like the casts used in Java.

-- Trent Apted 2005-03-20

Virtual Inheritance

So what's the deal with virtual inheritance? Have a look at this:

#include <iostream>
using namespace std;

struct Resource {
    int dummy;
    virtual void initMenu() {
        cerr << "Resource::initMenu()" << endl;
    }
};
struct Event {
    virtual void trigger() = 0;
};
struct Image : public Resource, public Event {
    int dummy;
    virtual void trigger() {
        cerr << "Image::trigger()" << endl;
    }
};

void* make_image() {
    return new Image();
}

int main() {        
    //(dynamic_cast<Event*>(make_image()))->trigger(); //won't compile
    ((Event*)make_image())->trigger();
    static_cast<Event*>(make_image())->trigger();
}

While it looks like the only function ever being called is 'trigger', when compiled (there are no warnings issued) and run, the output will be

Resource::initMenu()
Resource::initMenu()

Weird. This is because multiple inheritance requires multiple vtables to resolve virtual functions at runtime. If the inheritance is not also virtual, when a call is made on a type that doesn't know about the multiple inheritance, it will only look at the first vtable. In this case, this is the one in Resource. To fix the code above, we need to change the inheritance to:

struct Image : public virtual Resource, public virtual Event {

Now you get the expected result:

Image::trigger()
Image::trigger()

Note that the C-style cast also works, and there is no need for dynamic casting. You can not dynamic cast from a void* -- only types known to be an ancestor of the target type. Note also that there is now additional overhead for the function call.

Virtual inheritance does other stuff too. For example, if both Resource and Event inherited from a common parent, only one instance of that parent would be created when instantiating an Image. Without virtual inheritance, there would be two.

-- Trent Apted 2005-12-12

Bash (Bourne Again Shell)

Replacing file extensions and indirect variable access has traditionally been a pain in the Bourne Shell, with ugly constructs like `eval echo '$'$i` and `echo "$i" | sed -e 's/\.[^.]*$/.txt/'`. However, Bash has some nice shortcuts for these tasks; namely, ${!i} and ${i/%.*/.txt}, respectively. Try running the following:

#!/bin/bash

#variable indirection
i=1
while [ $i -le $# ] ; do
  echo -e '`eval echo '\''$'\''$i`\t= ' `eval echo '$'$i`
  echo -e '\t    ${!i}\t= ' ${!i}
  let i=$i+1
done
#replacing extensions
for i in "$@" ; do
  echo -e '`echo "$i" | sed -e '\''s/\.[^.]*$/.txt/'\''`\t= ' `echo "$i" | sed -e 's/\.[^.]*$/.txt/'`  
  echo -e '\t\t\t  ${i/%.*/.txt}\t= ' ${i/%.*/.txt}
done

The output should look something like this:

$ ./test.sh one.doc two.doc
`eval echo '$'$i`       =  one.doc
            ${!i}       =  one.doc
`eval echo '$'$i`       =  two.doc
            ${!i}       =  two.doc
`echo "$i" | sed -e 's/\.[^.]*$/.txt/'` =  one.txt
                          ${i/%.*/.txt} =  one.txt
`echo "$i" | sed -e 's/\.[^.]*$/.txt/'` =  two.txt
                          ${i/%.*/.txt} =  two.txt

Note that the second part doesn't handle files with more than one '.' in the filename. For those you'll need to specify the extension explicitly. e.g. ${i/%.doc/.txt}.

-- Trent Apted 2006-10-16

Stuff to help me program

Various Software Libraries
Basser's JDK1.2 API Docs
Dinkum C++ Library Docs
Dinkum C99 Library Docs
GNU libstdc++ Docs
The Graphics File Format Page
STI Profiler
Python Regular Expressions ANSI Escape codes