Monday, October 29, 2007

Fun with source control

So we're using Rational ClearCase for version control where I work, and for the most part it's a good tool, but I would really really like it if the tool made it more obvious which files were under version control and which were not, because I wound up breaking a build over the weekend after not adding one critical file to source control.

So, new rule -- I will always have at least two views. One will be for development, the other strictly for checking the build. Because modern technology is supposed to reduce the amount of work you have to do.

In other news, Gregor bit through the mouse cord on my computer last night. Whee.

Labels: ,

Monday, October 15, 2007

A brief discussion of C declarators

So while I'm waiting for a new virtual image to finish extracting so that I can recover from the disaster that was Friday afternoon, I thought I'd write up a brief introduction to C declarators.

Declarations in C can be confusing to someone not familiar with the language. Declarations like

int x;
float y;

are fairly straightforward (x is an integer, y is a single-precision real number), but then you come across something like this:

int *(*(*foo)[10])(int (*bar)[20]);

What does that even mean? How do you read declarations like that?

C follows the paradigm of declaration mimics use: in other words, the declaration of an object must look as much like how it will be used in the code that follows. This is probably best explained with a few examples.

Suppose we have a pointer to an integer, and we want to refer to the pointed-to integer value. To do this, we would use the dereference operator, '*':

*x = 5;
printf("%d\n", *x);


The type of the expression *x is int, so our declaration looks like this:

int *x;

The keyword int is the type specifier. It provides the basic type information for item being declared. The expression *x is called the declarator. It introduces the name of the thing being declared, as well as additional type information. In the pointer example above, x is the name of the variable, and its type is "pointer to int". However, the "pointerness" of x is given by the presence of the * operator in the declarator.

Let's look at a more complicated example. Suppose we have an array of pointers to int, and we want to refer to the integer value pointed to by element i of the array. We would write

x = *arr[i];

The declaration for the array arr would look like the following:

int *arr[N];

where N is a constant integer expression for the size of the array (I'm not familiar enough with C99's variable-sized arrays to provide a usable example). The type of arr is "N-element array of pointers to int." Again, the "int-ness" of arr is given by the type specifier int, but the "array-ness" and "pointer-ness" are given by the declarator *arr[N].

Note that the * and [] operators are bound to the identifier, not the type specifier. Whitespace makes no difference; in other words, the statements

int* x;

and

int *x;

are identical. This also means that the statement

int* x, y;

only declares x as a pointer; y is declared as a regular integer.

So what about the declaration

int *(*(*foo)[10])(int (*bar)[20]);

How do you read something like that? The trick is to find the leftmost identifier and work your way out, remembering that () and [] bind before * (IOW, *a[] is an array of pointer, (*a)[] is a pointer to an array, *f() is a function returning a pointer, and (*f)() is a pointer to a function). So in this case,

foo -- foo
*foo -- is a pointer
(*foo)[10] -- to a 10-element array
*(*foo)[10] -- of pointers
(*(*foo)[10])() -- to functions
(*(*foo)[10])(int (*bar)[20]) -- taking a pointer to a 20-element array of int
*(*(*foo)[10])(int (*bar)[20]) -- returning pointer
int *(*(*foo)[10])(int (*bar)[20]) -- to int

Labels: ,

Tuesday, August 21, 2007

It still lives!

Jesus, I haven't posted anything since March?! Shows you how much I've had to say about...anything.

Not that I have that much to say today. Just taking a lunch break from trying to get back into writing C++. It's kind of scary how much I forget when we're in the design phase. Getting back into coding always feels like that first day back in school after summer break; I wind up spending about three or four days making really stupid mistakes before everything clicks again. And I never really mastered all the intricacies of C++ formatted I/O. After having my brain damaged by C for a couple of decades, the C++ iostream model just doesn't make sense to me. Flexibility and extensibility are nice, but the cost in code complexity just doesn't feel like a fair tradeoff to me.

I just want to build a class that can read a script from a file and drive a test harness. Is that so much to ask?

Labels:

Wednesday, August 30, 2006

Scheduling tips

My team was discussing scheduling this morning, specifically how we need to adjust our schedule to account for uncertainties upstream. I was reminded of a bit of scheduling wisdom given to me by a project manager at another facility some years ago. He would get the best estimates he could, multiply that by π, and present that as the final schedule; as he put it, an irrational schedule called for an irrational number.

Labels:

Friday, August 18, 2006

Most Common Programmer Sayings


  1. But I didn't change anything!

  2. But what I changed shouldn't have made a difference!

  3. It works on my machine!

  4. Of course I checked it in!

  5. Yes, I made sure it built before checking it in!

  6. Yes, I have the latest version of the source tree!

  7. I thought you were handling that defect...

  8. Where's the spec?

  9. The problem's not in my code, it's in the API...

  10. Who the hell wrote this?!

  11. Where did that come from?

  12. Where did it go?

  13. Dammit, it was working yesterday, why isn't it working today?

  14. One semicolon can ruin your whole day...

Labels:

Thursday, August 17, 2006

Rules for being happy in software

1. Work for someone smarter than you.

1a. There's always someone smarter than you.

2. Never ask the questions "How hard can it be," or "What's the worst that could happen," unless you really want to know the answer.

3. Don't become overly attached to your job.

3a. It's better to be laid off early than late; you have a better chance of getting a severance, and there may still be jobs out there.

4. QA is not the enemy. Neither is the customer. Management occasionally is, but not that often, and to make up for they sometimes provide free pizza.

5. All programming languages suck. All platforms suck. All development environments suck. All text editors suck. All compilers suck. All database engines suck.

6. At some point in your career, you will come up with a brilliant idea that has nothing but disastrous consequences and will wind up as an entry in The Daily WTF. Accept that this will happen.

6a. You're never as brilliant as you think you are.

Labels: