Project-wide unique identifiers at compiletime

This topic is 4935 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hey, I'm currently working on a project which requires that at compiletime unique identifiers [ints in particular] can be created. Currently, this forces the users of my project to need to manually use different numbers, but this is not a valid solution. My question is: Is it possible to generate unique numbers which have a project-scope [ie the Visual Studio __COUNT__ macro would be acceptable, but it appears to work only in a single file's scope (perhaps someone knows how to tweak this so that it generates a global count)]. If worst comes to worst, I'm thinking I could make a custom build step which goes through and replaces my own macro (ie __GLOBALCOUNT__, or something less standards-breaking) with everincreasing numbers and then compiles that instead or something - but it's an awful lot of effort for something [which probably wouldn't work] which I would have thought was easier than it's turning out to be. --CJM

Share on other sites
//UniqueIDGen.h#ifndef _UNIQUE_ID_GEN_#define _UNIQUE_ID_GEN_class CUniqueIDGen{		//Integer used to generate unique ids		static unsigned int m_iIds;	public:		//constructor and destructor, do nothing		CUniqueIDGen(void) {}		virtual ~CUniqueIDGen(void) {}		/*********************************************		* Function:	GetID		*		* Return:		*	int: a unique id		*		* Purpose:	Function to generate unique class ids		*		*********************************************/		static unsigned int GetID();};#endif

//uniqueidgen.cpp#include "UniqueIDGen.h"unsigned int CUniqueIDGen::m_iIds = 0;/********************************************** Function:	GetID** Return:*	unsigned int: a unique id** Purpose:	Function to generate unique class ids**********************************************/unsigned int CUniqueIDGen::GetID(){	return CUniqueIDGen::m_iIds++;}

Call CUniqueIDGen::GetID() when you want a new, unique id.

Share on other sites
That's a nice solution, but unfortunately, it's runtime, not compiletime.

Share on other sites
We use perl scripts to modify a .h file during the build. Shell scripts would work just as nice, if your using windows then cygwin is your friend.

with vs.net pre and post build steps can be useful to you in implementing this!

Cheers
Chris

Share on other sites
What do you need it for?
The addresses of global variables are unique (assigned by the linker), and can safely be converted into an integer by casting it to intptr_t.
It's probably the easiest solution but also fairly limited.

Share on other sites
if all you need is a guid then use the prebuild stage to call guidgen and copy this guid into a predetermined .h file.

Cheers
Chris

Share on other sites
Thanks for the replies,

I'm currently writing a small library for use by other programmers working on the same project. Basically put, I've written all of the core parts, and only classes of functions [eg classes with only a void Foo();] need to be written by the other programmers.

What my system currently does [through the (mis)use of template specialisation] is allows them to write arbitrarily identified code - without bothering with any class declarations etc. My system picks them up at runtime and the application can immediately access them. There are other benefits that I won't go into, but the system works perfectly.

For example, the other programmers may write:

FC<1>::Foo()
{
//stuff goes here.
};

and this will immediately become available to the application (and be used by the application) after the next compile. However, if there are two FC classes which have template parameter <1> then the app won't compile.

I basically want to provide a simple way to generate unique IDs for these templates (and so a compiletime option is the only way to go). And there are potentially several hundred of these being written - so a manual solution doesn't really cut it.

Ah well, looks like a prebuild step to replace the __GLOBALCOUNT__ occurrences with a number, and a postbuild step to restore the old files is the way to go...

--CJM

Share on other sites
The __COUNTER__ counter macro doesn't work? I don't see why it wouldn't, it sounds like that this kind of thing is what it was made for.

Share on other sites
well maybe typeid can help..
#include <iostream>template <typename T>struct id{	static const int Id;};template <typename T>const int id<T>::Id = reinterpret_cast<int>(typeid(id).name());struct foo : id<foo>{};struct bar : id<bar>{};int main(void){	std::cout << "foo.Id == " << foo::Id << "\n"		<< "bar.Id == " << bar::Id << "\n";	return 0;}

Share on other sites
You don't actually need unigue identifiers across source files. Just always declare the class inside an anonymous namespace.

file1.cpp
namespace {  FC<1>::Foo() {}}

file2.cpp
namespace {  FC<1>::Foo() {} //No problem!}

You only need unigue identifiers within a single cpp file. Even if the types look like they would collide, the anonymous namespaces keep the declarations from leaking out.

• What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

(You must login to your GameDev.net account.)

• 15
• 9
• 11
• 9
• 9
• Forum Statistics

• Total Topics
634135
• Total Posts
3015754
×