UUIDs in 10 Languages — Part 1: UUID Generation in C and C++
UUIDs aren’t just for high-level application frameworks. They’re also essential in the foundations of operating systems, databases, and distributed protocols — which often means C and C++.
But generating UUIDs in these languages isn’t as simple as calling uuid()
in Python. You have to pick the right libraries, manage memory properly, and often handle formatting manually.
Here’s how to generate UUIDs properly in C and C++, with idiomatic examples and common pitfalls.
⚙️ C: Using `libuuid` (Linux/Unix)
Most Linux systems ship with libuuid
, part of the util-linux package.
🔧 Installation
On Ubuntu/Debian:
sudo apt install uuid-dev
📦 Basic UUIDv4 Example in C
#include <stdio.h>
#include <uuid/uuid.h>
int main() {
uuid_t uuid;
char uuid_str[37]; // 36 chars + null terminator
uuid_generate_random(uuid);
uuid_unparse_lower(uuid, uuid_str);
printf("Generated UUID: %s
", uuid_str);
return 0;
}
✅ Notes
uuid_generate()
is a hybrid generator (might use MAC + time or randomness)uuid_generate_random()
forces version 4 (fully random)uuid_unparse_lower()
is preferred for lowercase formatting
🪟 Windows: `UuidCreate` and `UuidToString`
📦 Example in Windows (C)
#include <rpc.h>
#include <stdio.h>
#pragma comment(lib, "Rpcrt4.lib")
int main() {
UUID uuid;
UuidCreate(&uuid);
RPC_CSTR str;
UuidToStringA(&uuid, &str);
printf("UUID: %s
", str);
RpcStringFreeA(&str);
return 0;
}
⚠️ Caveats
- Windows APIs generate UUIDv1-style (time + MAC)
- Requires linking against
Rpcrt4.lib
- Strings are allocated — remember to free them!
💡 C++: Use Boost.UUID for Cleaner Code
The Boost library provides a powerful and portable UUID implementation.
🔧 Installation (Ubuntu)
sudo apt install libboost-all-dev
📦 Example (UUIDv4 in C++)
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <iostream>
int main() {
boost::uuids::random_generator gen;
boost::uuids::uuid id = gen();
std::cout << "UUID: " << id << std::endl;
return 0;
}
📦 Alternative: Name-based UUID
#include <boost/uuid/name_generator.hpp>
boost::uuids::name_generator gen_ns(boost::uuids::ns::dns());
auto id = gen_ns("example.com");
🧪 Testing and Validating UUIDs
Whether you're generating or parsing UUIDs:
- Validate against a regex:
[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}
- Use Boost’s comparison operators (
==
,<
, etc.) - In C, verify
uuid_compare()
if checking equality
🧠 Best Practices
Concern | Recommendation |
---|---|
Format safety | Use uuid_unparse_lower() in C |
Version control | Prefer uuid_generate_random() for UUIDv4 |
Platform portability | Prefer Boost in C++ |
Thread safety | Most UUID APIs are thread-safe, but check docs |
Memory management | Always free RPC strings on Windows |
🧰 Where You'll See This in the Real World
- Filesystem labels (
ext4
uses UUIDs) - Systemd machine IDs
- Kubernetes node IDs (container runtimes)
- Embedded platforms and serial number IDs
- Inter-process correlation (Windows RPC, UNIX daemons)
Final Thoughts
UUIDs in C and C++ may take more setup — but they’re a powerful tool when used correctly.
Whether you’re building a high-performance game engine, a system daemon, or a distributed storage node, these identifiers provide traceability, correlation, and uniqueness — all with the performance and precision these languages demand.
🧱 Part 2 up next: Rust, Go, and C# — with even more expressive UUID options.