Blog
This is (or will be) a collection of my ponderings on computer science and life in general.
There is an atom feed here ;)
Clearly, as the site is not dynamic, there's no way to directly comment on the posts here. Your best bet is to send me an email.
Wed, 29 Sep 2010 11:53:16 +0100
Some notes on C#
So I have a job interview on friday for a .NET developer position. Having not really done much with .NET in the past (which the employer doesn't mind so long as I am willing to learn) I decided to brush up on the main differences between this and the other languages I use which these days are; C, C++, assembly and Java. There doesn't seem to be much point comparing C or assembly to the .NET framework, so I'll try and get the main points compared to the other two.
This is written for my own reference more than anything else, so YMMV. If a feature is very similar to that in another language I will just say that rather than explaining it.
Basics, object model etc
Like Java, the object model is rooted in a single class; object, which
is a native type.
Operator overloading is allowed, similar syntax to C++ but without stuff like returning non const references to *this etc. || and && can't be overloaded. == and this->Equals() have different meanings (== is reference equality, Equals() is value equality.)
Class definition is similar to C++, except the default inherited visibility is public (don't seem to be many examples of using protected or private, but then it was rarely used in C++ as well - maybe it doesn't exist?). Same as Java in that it always inherits from System.object. There is no semicolon on the end of the class definition. No multiple inheritance, like Java has a special type of class called an interface (with the same keyword) which only contains pure virtual member functions.
public class Foo : SuperClass, IInterface1, IInterface2 {
}
Strings in C# are immutable in a similar manner to Java. However they can also contain null characters - presumably this is because of the weird double-null-terminated-string-list structure that Win32 loves so much. There is probably some API function to convert between these and collections of strings. .NET strings are UTF-16, which is fine as Windows NT has always used unicode internally (hence all the Ex/A suffixes in the API)
Generics in C# (and .NET in general) are more similar to Java's generics than C++
templates. They essentially cast up to object and back the whole time.
Collections in C# typically inherit from IEnumerable<T>. The for-each syntax
is as follows:
foreach(Thing i in setOfThings) {}
compared to the Java:
for(Thing i : setOfThings) {}
Exceptions
C# has no checked exceptions, like C++. As the standard libraries and the runtime make use of exceptions, you have to make the same assumption as in C++ when working with exceptions. Namely, that any line of code could throw. This makes some sense, as checked exceptions in Java were not always used correctly, for example:
String s = in.readLine();
int x=0;
try {
x=Integer.parseInt(s);
} catch(NumberFormatException e) {
...
}
Where NumberFormatException is not a checked exception,
even though it is likely to be thrown. Of course the argument could be that
this code should not use exceptions in the first place, as an abitrary string
is less than likely to be a valid integer. (of course they added tryparse, but that has
it's own problems.
The syntax for exceptions is pretty much the same as Java, with try,
catch and finally. All exceptions inherit from the base class
Exception.
Naming conventions
C++ doesn't really have a standardised naming convention, with each project defining their own. Java does, so I'll point out the main differences for comparison.
| Usage | Java | C# |
|---|---|---|
| Class names | Starts with a capital, subsequent words also. | The same |
| Member function names | camelCase | PascalCase |
| Member variable names | camelCase | PascalCase |
| Paramter names | camelCase | camelCase |
Will add more later...
Sun, 19 Sep 2010 14:40:17 +0100
Some changes
So I've moved some things around on this site. The intention was to upload some other code, but most of the software I've written the last year or so was for other people so I can't really post that here.
I added the slowdown program, which is of limited utility but it's better than pastebinning it any time somebody wants it. I may try and make it into a more general purpose filter so you can simulate being on a *nix box over an old 300 baud modem (though it'd probably be easier to use a serial console and just set the baud rate.)
I'm going to try and clean up my BrainFuck compiler to upload it - was written in a hurry a good while ago so not very good by way of commented code. It produced the fastest code of any other compiler I could find at the time. That said there are probably a few optimisations that could be made - say buffering IO rather than read()/write()-ing single bytes at a time (as system calls aren't cheap).
Finally I'll try and get some version of my OS up. The problem with that, however, is that most of the ideas in it are proof of concept and testing rather than anything useful. On the other hand there are a number of reasonable features:
- Kernel land:
- Pre-emptive multitasking (not multi-threading, but wouldn't be difficult - not totally convinced shared memory is the best solution for parallelism)
- Basic services - cpio-based FS, simple VFS, pipes etc
- Multiboot compliant - boots via GRUB or PXELINUX.
- Some POSIX-ish system calls; fork, exec, wait,mmap (anonymous memory only atm), read/write/open/close, poll (in leiu of select(). The system is not intended to be POSIX-compliant, but why mess with a good thing.
- Loads ELF executables (staticly linked only)
- Support for user space drivers via message passing - not used apart from a small test of the feature (reimplemented the keyboard driver, but the one at boot time is still the in-kernel one).
- Partial (and probably incorrect) ANSI terminal support.
- User land:
- Minimal shell, supports chaining commands together and backgrounding them.
- Pile of test programs for system calls (e.g. wait/exec, pipes, causing gpf/page fault etc)
- Minimal C library implementation (some stdio calls, some with different semantics). Really more a set of functions likely to be used in a number of apps.
- Simplified C implementation of 2D Turmites (Testing VGA support)
- Nibbles/snake game (testing the terminal emulator). It's actually quite hard - I've not beaten it yet.
But the code in the kernel itself is a bit fragmented, as I didn't know what I was doing when I started. I will get around to writing a new version at some point, but I've other drains on my time at the moment. The User-Mode side is ok though - however chunks of it won't be binary compatible with the rewrite. For the time being, anyone who wants a copy can ask for one, but it's not going on here yet.
Wed, 03 Feb 2010 06:52:38 +0000
well i was foolish
Heh, turns out it wasn't a firefox issue, but a Gentoo one (and in fairness, seeing as it's not the mozilla binaries I shouldn't have mentioned it anyway.) Gentoo uses the system SQLite libraries, which were not compiled with secure delete enabled (or availiable as a use flag).
My bad.
Wed, 03 Feb 2010 05:45:22 +0000
Firefox doesn't really clear your private data
While waiting to head into uni for a lecture, I was clearing out some things in
my /home directory. Poking around in my
Firefox profile directory, I noticed a few
large .sqlite files (places.sqlite, cookies.sqlite etc). Now I set
Firefox to clear private data on exit. It removes all traces of the
history in the user interface, so it was a bit odd.
On opening places.sqlite with a text editor (btw these are binary files, but you can still make it out) , I saw practically every site I had visited since 2004. The same went for the cookies and site preferences. I killed firefox, deleted these files and started it again, clicked round a few sites, cleared private data and quit. Same thing, it had kept my history and cookies.
I have to admit, there were not a small amount of conspiracy theories flying around my head at that point. A simple cron job to delete the data would not suffice, as there are certain things I do want to keep (e.g. which sites to accept cookies from) and if FF is running when the job executes (as is likely to be the case), firefox will hold the lock on the file anyway, and next time it syncs to disk it'll all be restored.
I started thinking about a small tool to do the file wiping, which i could add to my /usr/bin/firefox script. Reading about the sqlite file format it soon became clear what was happening, rather than rebalance the whole B-Tree, sqlite was just adding the deleted nodes to a free list, not actually zapping them from the file. Reading further it says sqlite provides two options to solve this:
- Use the
VACUUMcommand to flush the changes out of the database, compacting it. link - Set the database as auto-vacuum This will do it, and to be honest I'm unsure why Mozilla doesn't do it by default on exit (could maybe argue a performance penalty, but it takes a tiny fraction of a second on my box, and if somebody has set it to erase this data they are not going to moan).
Neither of these would be difficult for the Firefox people to implement. I'm currently compiling the latest firefox and sqlite to verify this is still present (was still on 3.5.2). After which I'll file a bug report.
In the meantime though, you can either just delete the files by hand (with
firefox not running) or VACUUM it yourself, again when firefox
isn't running
This can be done quite easily in the shell, just load the database with
sqlite's interface (sqlite3 in this case) and type
VACUUM; then quit (ctrl+d works fine). Again, if you try
doing this with firefox running, you'll get something like:
richard@armada ~/.mozilla/firefox/k6telub8.default $ sqlite3 places.sqlite SQLite version 3.6.22 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> VACUUM; Error: database is locked sqlite>
An easier way is probably to loop over them all and vacuum them (again from the firefox profile directory):
$ ls *.sqlite | while read > do > echo "VACUUM;" | sqlite3 "$REPLY" > done
It's worth noting that this won't clear out stuff like cookie preferences. If you go onto the options and clear them, then run this script it will remove traces (as they haven't been dropped from the database).
Sat, 23 Jan 2010 20:13:25 +0000
Making ROX-Filer respect folder.jpg thumbs
As you may know, I'm a big fan of ROX filer as it's very easy to use, and fast. However my main workstation also functions as a file server for my media centre downstairs (XBOX running XBMC, which is very nice as well).
In XBMC you can set custom thumbnails for directories, placing a file
folder.jpg inside. Presumably this is for compatibility with
Windows Media Centre/Media Player, but couldn't say tbh (don't use Windows, so
it's irrelevant). It also allows you to set icons for individual files with
filename.tbn.
I wanted ROX to show these icons on my workstation when I viewed said directories, I knew there was a hook somewhere, as ROX has a feature known as 'AppDir's, which is similar to the way RISC-OS (from Acorn) did it.
The hook turned out to be, instead of looking at ./folder.jpg, it
went to ./.DirIcon. So a simple loop in bash suffices:
find -name folder.jpg|while read do ln -s folder.jpg "`dirname "$REPLY"`/.DirIcon" done
Easy eh? Fair enough it uses another inode, but with most of the files being >100mb, I'm not likely to run out.
Sat, 23 Jan 2010 18:53:32 +0000
First semester of MSc
After the summer i started a masters course in Advanced Computer Science (still at Liverpool). To be honest the first month and a half was pretty unbearable, as the university had not confirmed my place until the day i was meant to register. (whilst I was still in Caithness).
This caused a number of problems, the primary one being that I was in desperate need of accomodation. I checked out LSH, but there was nothing hopeful. Also, I've been burnt with LSH accredited landlords and properties in the past so thought it was best to avoid the whole thing. After about 6 weeks of couch surfing (with some surprisingly understanding/generous friends) I found a shared house not far from where I lived two years back.
The MSc itself seems to be going well.. Exams are this week though (but I had another post I wished to make and figured that this one should come first. Privacy and Security (COMP522) is quite enjoyable, and I'll be walking into the exam with 25% already because I got perfect scores on the assessments. Advanced algorithmic techniques is slightly worse, but most of that is due to the practicals being poorly specified, deliverables being misleadingly stated, and the ommision of a number of things (which actually account for most of the work - for example a simple graph algorithm is not difficult, writing something to read in a graph frmo a text file is much more fiddly than the algorithm itself.)
Anyway, later ;)
Mon, 20 Jul 2009 14:27:41 +0100
Initialisation of vtables in static globals
While working on my kernel, I came across an odd problem that had been making me consider rewriting in C (though I may end up doing that anyway to reduce complexity) - Virtual functions did not work, and the results were odd.
extern Console *con;
class Base {
public:
virtual void do_something() {
con->print("\nCalled base class\n");
}
};
class Sub : public Base {
public:
virtual void do_something() {
con->print("\nCalled derived class\n");
}
};
Base b1;
Sub s1;
Base *b2;
void test_it() {
s1.do_something();
b1.do_something();
b2=&s;
b2->do_something();
Sub::Sub(s1);
s1.do_something();
Sub s2;
s2.do_something();
}
The odd thing is that even though the static instances do not have any attributes
you could expect (at least for s1) that the vtable would be set
as static data (or even rodata as the type can not change).
Of these, s2 and b2 perform as expected - on s1 however the vtable is uninitialised. This means that (on bochs/qemu anyway) you are dereferencing a null pointer (which will cause a panic).
Once the constructor is called (Sub::Sub(s1)) it works as you'd expect. Was just
a bit weird when certain things worked and others didn't - I had seriously expected it to
pre-initialise the classes as the data was known at compile time. Should have read the ABI spec more
thoroughly. ;)
Tue, 30 Jun 2009 20:19:20 +0100
Stuff i need to get on this site
Here are a few things I want to get here eventually. Just a case of writing them up.
- Slowdown - for emulating slower bauds on modern terminals, either for nostalgia or watching old tty animations.
- My honors project - OpenGL based turing machine/turmite simulator. It was pretty cool.
- Brainfuck compiler - old project, but it did a good job and the resulting code was faster than that of any other compiler I could find at the time.
Tue, 30 Jun 2009 19:11:18 +0100
Graduated
Well, I'm done with university now. I got a 2:2 which was less than I was expecting. However it is still a degree. The job hunt is occuring and there are a few promising leads - just nothing quite yet.
As a result I have had to relocate this site, there are a few issues here:
Fasthosts subdomains don't work right. They frame the index page - which means you cannot link to somewhere inside a subdomain. Even due to my dislike of javascript I was forced to remedy this with small (2-line) script at the bottom of the page.
Google points to my university site, and having not messed with .htaccess in a long time I couldn't get it right. however it works now
On a different note I've been working on a couple of personal projects, such as a software 3d renderer. It is capable of loading simple (as in triangles only, no textures or normals - but then the normals for triangles are implicit). At the moment the only thing I have been testing with is the Stanford Bunny. I intend to add in at least gouraud shading and possibly texturing.
Relating to this, I'm going to have to write my own filling/shading/texturing system, which could probably be released as a seperate project - at the moment I am using SDL_gfx just so I could concentrate on the mathematical aspects. The other thing I see a lot in code that uses SDL is the number of times people switch(){} on the pixel format of a surface. Wouldn't it be better to write a seperate method for each format rather than doing a comparison each time?
Anyway, that's all for now - I will try and update this more often...