Date: Wed, 22 Nov 2023 12:06:14 +0000
Lots of people make use of the __COUNTER__ macro in their code for
generating unique identifiers and unique types, and for a unique
incrementing number.
Last week I wrote code that combined __COUNTER__ with __FILE__ to get
a string which hopefully would be unique for the entire program.
So then I was thinking, what if the preprocessor could help us here
and give us a 128-Bit random number? What if there were to be five new
macros that would expand as follows:
#define __UUID__ 0f234c3ac9ec4d7bab8e2fcac3da8a5c
#define __UUIDstr__ "0f234c3ac9ec4d7bab8e2fcac3da8a5c"
#define __UUIDstrH__ "0f234c3a-c9ec-4d7b-ab8e-2fcac3da8a5c"
#define __UUIDint128__ 0x0f234c3ac9ec4d7bab8e2fcac3da8a5c
#define __UUIDint64__ 0x0f234c3ac9ec4d7b, 0xab8e2fcac3da8a5c
Of course __UUIDint128__ can only be used on compilers that have an
unsigned integer type at least 128 bits wide and which allow 128-Bit
literals. Here's some sample usages:
#include <cstdint>
#include <iostream>
using std::cout, std::endl;
#define CONCATx(a,b) a##b
#define CONCAT(a,b) CONCATx(a,b)
int main(void)
{
unsigned CONCAT(some_variable_,__UUID__) = 68u;
some_variable_0f234c3ac9ec4d7bab8e2fcac3da8a5c = 67u;
cout << "Your build key to give to production is {" <<
__UUIDstrH__ << "}\n";
std::uint64_t my_uuid[2u] = { __UUIDint64__ };
__uint128_t myuuid = __UUIDint128__;
}
Furthermore, to do away with the need for the CONCAT macro, I suggest
that the following line:
unsigned CONCAT(some_variable_,__UUID__) = 68u;
can be simplified to:
unsigned some_variable_###__UUID__### = 68u;
So the three hash symbols (or pound symbols in the US) are used by the
preprocessor to concatenate two sequences of characters together
without a space between them. So you could also use this tripple-hash
in your own code, such as:
#define monkey donkey
unsigned myvar_###monkey### = 7;
myvar_donkey = 8;
generating unique identifiers and unique types, and for a unique
incrementing number.
Last week I wrote code that combined __COUNTER__ with __FILE__ to get
a string which hopefully would be unique for the entire program.
So then I was thinking, what if the preprocessor could help us here
and give us a 128-Bit random number? What if there were to be five new
macros that would expand as follows:
#define __UUID__ 0f234c3ac9ec4d7bab8e2fcac3da8a5c
#define __UUIDstr__ "0f234c3ac9ec4d7bab8e2fcac3da8a5c"
#define __UUIDstrH__ "0f234c3a-c9ec-4d7b-ab8e-2fcac3da8a5c"
#define __UUIDint128__ 0x0f234c3ac9ec4d7bab8e2fcac3da8a5c
#define __UUIDint64__ 0x0f234c3ac9ec4d7b, 0xab8e2fcac3da8a5c
Of course __UUIDint128__ can only be used on compilers that have an
unsigned integer type at least 128 bits wide and which allow 128-Bit
literals. Here's some sample usages:
#include <cstdint>
#include <iostream>
using std::cout, std::endl;
#define CONCATx(a,b) a##b
#define CONCAT(a,b) CONCATx(a,b)
int main(void)
{
unsigned CONCAT(some_variable_,__UUID__) = 68u;
some_variable_0f234c3ac9ec4d7bab8e2fcac3da8a5c = 67u;
cout << "Your build key to give to production is {" <<
__UUIDstrH__ << "}\n";
std::uint64_t my_uuid[2u] = { __UUIDint64__ };
__uint128_t myuuid = __UUIDint128__;
}
Furthermore, to do away with the need for the CONCAT macro, I suggest
that the following line:
unsigned CONCAT(some_variable_,__UUID__) = 68u;
can be simplified to:
unsigned some_variable_###__UUID__### = 68u;
So the three hash symbols (or pound symbols in the US) are used by the
preprocessor to concatenate two sequences of characters together
without a space between them. So you could also use this tripple-hash
in your own code, such as:
#define monkey donkey
unsigned myvar_###monkey### = 7;
myvar_donkey = 8;
Received on 2023-11-22 12:06:27