File-Unique Identifier

Sometimes one needs to supply an identifier for something that will never be referenced again. The most common occurrence is a local object of some type whose construction and destruction side-effects are wanted at the beginning and end of the scope it exists in, respectively. Having to come up with a name is both tedious and unclear, since the name will serve no purpose in the code. If it were possible, providing no name would make the intent clearer.

This can be achieved with a macro that expands to an identifier that is unique to that file.


    #define CONCAT_3_( a, b )  a##b
    #define CONCAT_2_( a, b )  CONCAT_3_( a, b )
    #define CONCAT( a, b )     CONCAT_2_( a, b )

    #define UNIQUE_NAME    CONCAT( UNIQUE_NAME_, __LINE__ )

For example, this file


    void f() {
        Lock UNIQUE_NAME;
        // ...
    }

will expand to


    void f() {
        Lock UNIQUE_NAME_2;
        // ...
    }

In the CONCAT macro, the seemingly-redundant helper macros (CONCAT_2_ and CONCAT_3_) are needed due to particulars of the preprocessor.

Generally, this construct will only be needed in a source file (and not a header). This makes it unlikely for it to clash with anything else. If it's needed in a header file, care must be taken that the name can't clash with any other identifier, because a clash may not show up until the header is integrated with another header file that happens to have an identical UNIQUE_NAME. :-)


Blargg's C++ Notes