Thursday, June 11, 2009

You're going to think I'm an idiot, but...

I thought I'd put down for my future reference some things I learned today about C...

I've been in high level languages pretty much my entire career. I learned Java first, even built a game and game design tooling in Swing, so I've been in the wars. Since then Ruby, some Smalltalk, lots of JS, lots of C#, some Python, some Erlang. Probably a couple others, if I really think about it. Point is, those are all high level languages - automatic garbage collection and quite a bit of protection between you and the computer.

Not that I'm hitting buffer overruns and all the other classic nasties yet, mostly because of the circumstances of my encounter with C.

Basically I'm adapting existing embedded driver code from ESDL - taking the bits I want because my API's going to end up running to about a page and I'll do all the OpenGL work in C. This means that there's quite a lot of code there, written by pretty good C programmers - some of them the original ddll:_/_ authors, some of them Dan Gudmunsson and whoever he was working with for Wings3D. They're doing things that seem to me to be pretty clever, but some of them just flew under my radar the entire morning. For example, it was a great surprise to me when I eventually noticed that you could do this:

#include whatever
#define aCollection = {
#include stuffInTheCollection
}

Which works because #include is a literal compile time macro, which inserts the content of the file directly into the source (maybe not literally, but that's what I'm guessing - it certainly behaves that way). If you're not looking for that sort of thing to happen, you just overlook it over and over, because that part of the file is just usings and imports, and of no great significance unless you're trying to disambiguate where something came from. Which still happens - a LOT - and is bloody hard to work out sometimes. I haven't yet seen any really bad ones, but I reckon if you were overly clever you could string together a bunch of macros and it would be literally impossible to find any trace of your referenced functions in the source code. Grep would be useless and so would I.

Oh, the other interesting thing about the above code is that it implies that this is a valid header file:

{1,2,3},

trailing comma intended. Very grating if you're coming down from something like Java which just doesn't tolerate syntactic malformation at all (except for itself, but that's another story).

So as far as I can guess, C is just basically a huge undifferentiated clump of functions - sort of mash everything in every included file into one file and you'd have the contents of your binary. Sounds obvious, when you put it like that, but I keep looking for objects and scopes and namespaces and stuff - containers to help me look for my functions. They're not there.

More soon, probably (and eventually I'll finish off the silver standard NewLisp InkCanvas and post that too.

No comments:

Post a Comment