Fog Creek Software
Discussion Board

Welcome! and rules

Joel on Software

CVS/RCS IDs in C# files

Some people argue about it, but it is generally considered a good practice to instrument all files in C/C++ world with static strings containing the identification information for  the file that CVS automatically updates, e.g.:

#ifndef lint  /* to avoid "...unused" warnings */
static const char RCSid[] = "$Id";

I have just started doing my baby steps in C#, which doesn't allow global objects. While I can think of various elaborate ways to circumvent this problem (for example by embedding the aforementioned string into one of the classes or by creating a private class with static id) I'm pretty sure I'm not the first one to face this problem. I wonder if there are already established common sense way to achieve this task...

Thanks in advance,

Alexander L. Belikoff
Monday, December 15, 2003

Can I ask... why do you care? Given your code above about unused warnings, it sounds like you're not even using that value anyway.

Brad Wilson (
Tuesday, December 16, 2003

Yes, you can ask. :-) The fact that I don't want to see an "unused variable" warning when I pass the code through lint doesn't mean that I don't want this variable to be compiled in when I build software. The whole point is not in using this variable programmatically but rather in being able to extract such strings from an executable or library to figure out which revisions of files this executable consists of. In case of CVS/RCS you can run 'ident' program on your binary and get a long list of files, like:

$Id: undo.c,v 1.7 1994/11/13 04:25:44 alm Exp $

Alexander L. Belikoff
Tuesday, December 16, 2003

Look into attributes, look for the topic "Extending Metadata Using Attributes". Perhaps the DescriptionAttribute?

or the RcsIDAttribute:

Tuesday, December 16, 2003

An intelligent linker has every right to throw those things away, so you shouldn't expect something that's unused to stick around in the final binary.

Brad Wilson (
Wednesday, December 17, 2003

perhaps I don't understand attributes, but aren't they basically a form of exported metadata? so the linker can't throw them away, as they're meant to be read by other components.

Thursday, December 18, 2003

I wasn't talking about attributes. I was talking about his unreferenced, unused static strings.

Brad Wilson (
Thursday, December 18, 2003

In my Unix based C++ toolkit I've built a singleton that's used to collect CVS IDs. Each code file has some stuff in the anonymous namespace that takes the $Id$ value from the .cc file and the .h file and passes them to my version string singleton.

This gives me three good things:

(1) None of the version strings are considered unused, because they are all used when they're passed to the singleton during initialisation.

(2) I can programmatically get access to the list of version strings for all the linked object files. This is useful for all sorts of things (eg: when my FogBUGZ object is triggered to fire a bug report into FogBUGZ, I can dump the list of program object versions in as supplementary data).

(3) My version string singleton registers itself with my interactive debug mechanism, so I can query the version list via my interactive network aware debug mechanism. It's good being able to reach into a customer site via a VPN and ask an application about the version of all the object files it's built from.

Some adaptation of this should be pretty easy in C#.

Andrew Lighten
Sunday, January 4, 2004

you should be able to do all of this with attributes, though they may not be centrally registered. you can certainly walk the assembly and find all the objects somehow.

Monday, January 5, 2004

*  Recent Topics

*  Fog Creek Home