# Global comptime counter

**URL:** <https://ziggit.dev/t/global-comptime-counter/2874>\
**Category:** Help\
**Tags:** comptime\
**Created:** [January 16, 2024, 12:05am UTC](https://ziggit.dev/t/global-comptime-counter/2874 "2024-01-16T00:05:46Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![slonik-az](https://ziggit.dev/letter_avatar_proxy/v4/letter/s/ebca7d/32.png) [@slonik-az](https://ziggit.dev/u/slonik-az)\
**Post date:** [January 16, 2024, 12:05am UTC](https://ziggit.dev/t/global-comptime-counter/2874/1 "2024-01-16T00:05:47Z")

</div>

I am curious whether it is possible to define a global `comptime` function `cntUp()` that returns sequential `comptime_int` each time it is called at comptime. I want to use it as a `comptime` source of unique IDs.

---

<div class="post-metadata">

**Author:** ![ianprime0509](https://ziggit.dev/user_avatar/ziggit.dev/ianprime0509/32/1226_2.png) [@ianprime0509](https://ziggit.dev/u/ianprime0509)\
**Post date:** [January 16, 2024, 1:53am UTC](https://ziggit.dev/t/global-comptime-counter/2874/2 "2024-01-16T01:53:21Z")

</div>

Not really: there are some tricks you could try using with closures over `comptime var` in the current compiler, but these loopholes are planned to be closed to prevent this: [make closure over comptime var a compile error; comptime vars become immutable when they go out of scope · Issue #7396 · ziglang/zig · GitHub](https://github.com/ziglang/zig/issues/7396)

There was also a post a little while ago with some ideas on implementing something like this: [C/C++ macro challenge #1: BOOST\_PP\_COUNTER](https://ziggit.dev/t/c-c-macro-challenge-1-boost-pp-counter/2235) For example, even if you don’t want to rely on `comptime var` loopholes, you can still (ab)use properties such as the uniqueness of `opaque{}` types to at least get unique ID values, although they won’t be sequential.

---

<div class="post-metadata">

**Author:** ![Cloudef](https://ziggit.dev/user_avatar/ziggit.dev/cloudef/32/1370_2.png) [@Cloudef](https://ziggit.dev/u/Cloudef)\
**Post date:** [January 16, 2024, 2:53am UTC](https://ziggit.dev/t/global-comptime-counter/2874/3 "2024-01-16T02:53:11Z")

</div>

It’s possible to make some things unique with `@src()`

> [@Allocator/manager for shared objects?](https://ziggit.dev/t/allocator-manager-for-shared-objects/2757/3):
>
> I think there’s no good solution for preventing copy until [https://github.com/ziglang/zig/issues/7769](https://github.com/ziglang/zig/issues/7769) or something similar is in the language. The closest I can do right now is const std = @import("std"); fn Shared(comptime T: type, comptime Src: std.builtin.SourceLocation) type { return struct { comptime uniq: std.builtin.SourceLocation = Src, ref\_count: usize = 0, value: \*T, fn init(value: \*T) @This() { return .{ .value = value }; } …

---

<div class="post-metadata">

**Author:** ![slonik-az](https://ziggit.dev/letter_avatar_proxy/v4/letter/s/ebca7d/32.png) [@slonik-az](https://ziggit.dev/u/slonik-az)\
**Post date:** [January 16, 2024, 3:13am UTC](https://ziggit.dev/t/global-comptime-counter/2874/4 "2024-01-16T03:13:15Z")

</div>

Similar to `opaque{}``struct{}` gets a unique typeID and it does not waste a byte. I am using it as a unique anchor.

---

<div class="post-metadata">

**Author:** ![AndrewCodeDev](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@AndrewCodeDev](https://ziggit.dev/u/AndrewCodeDev)\
**Post date:** [January 16, 2024, 5:04pm UTC](https://ziggit.dev/t/global-comptime-counter/2874/5 "2024-01-16T17:04:11Z")

</div>

We had a whole thread about this: [C/C++ macro challenge #1: BOOST\_PP\_COUNTER](https://ziggit.dev/t/c-c-macro-challenge-1-boost-pp-counter/2235)

Edit - just saw @ianprime0509’s post on the same thing. Most of the solutions right now are kind of hacky. A builtin would be nice or doing pre-processing on the file during a build step would also be possible. Sequentially replace the text and increment a counter…

---

<div class="post-metadata">

**Author:** ![Sze](https://ziggit.dev/user_avatar/ziggit.dev/sze/32/496_2.png) [@Sze](https://ziggit.dev/u/Sze)\
**Post date:** [January 17, 2024, 11:25am UTC](https://ziggit.dev/t/global-comptime-counter/2874/6 "2024-01-17T11:25:56Z")

</div>

> [@AndrewCodeDev](#):
>
> A builtin would be nice or doing pre-processing on the file during a build step would also be possible. Sequentially replace the text and increment a counter…

I like that creating such a global counter is difficult, because so far I haven’t seen a good reason to make such a feature easy within the language, creating and using a global counter like this seems like a bad idea to me.

It seems to me that the want to have things like this may be caused from `c/c++`-isms like the awful singleton pattern (or things like it), I think the solution is to stop relying on some global order being enforced across an entire source tree that relies on side effects, which in the worst case puts bad constraints on what the compiler is allowed to do in parallel.

If you need a set of things to have unique indizies, it seems better to me to put these things in one place, for example an array and use their array index as that thing that identifies them. Don’t write cute magic code.

I would be much more interested in the question “How can we rewrite something that relies on hacky global comptime counters, to something that is more ziggy”. Don’t bring the hacky c/c++ stuff into another language, that is my opinion on the topic.

---

<div class="post-metadata">

**Author:** ![chung-leong](https://ziggit.dev/user_avatar/ziggit.dev/chung-leong/32/999_2.png) [@chung-leong](https://ziggit.dev/u/chung-leong)\
**Post date:** [January 17, 2024, 1:43pm UTC](https://ziggit.dev/t/global-comptime-counter/2874/7 "2024-01-17T13:43:26Z")

</div>

In most usage scenario we don’t actually need a comptime value. We’d use the counter to generate a sequence for use at runtime. In theory, it should work just as well if we generate it at linktime instead. That would resolve the conflict with incremental compilation.

I imagine it working like this. Instead of counters we have the concept of linktime sets, to which we can add things at comptime:

```zig
// @linkSetAdd(comptime T: type, comptime []const name, comptime thing: anytype) T 

const id = @linktimeSetAdd(u8, "Hello world", .{ .random_literal });

```

We can see if things are in a set:

```zig
// @linkSetContains(comptime []const name, comptime thing: anytype) bool 

if (@linktimeSetContains(u8, "Hello world", .{ .random = true })) {
    // do something if a module added .{ random = true } to set
};

```

We can also get the size of the set:

```zig
// @linkSetSize(comptime []const name) usize 

if (index < @linktimeSetSize(u8, "Hello world")) {
    // do stuff
};

```

Behind the scene, these calls get translate to references to variables in a hidden module to be generated automatically by the linker:

```zig
const id = @import("linktimeSet(Hello world)").@"add({ .random_literal }): u8";
// ...
if (@import("linktimeSet(Hello world)").@"has({ .random_literal }): bool";
// ...
if (index < @import("linktimeSet(Hello world)").@"size(): usize") {
// ...

```

---

<div class="post-metadata">

**Author:** ![slonik-az](https://ziggit.dev/letter_avatar_proxy/v4/letter/s/ebca7d/32.png) [@slonik-az](https://ziggit.dev/u/slonik-az)\
**Post date:** [January 17, 2024, 1:45pm UTC](https://ziggit.dev/t/global-comptime-counter/2874/8 "2024-01-17T13:45:21Z")

</div>

> [@Sze](#):
>
> I like that creating such a global counter is difficult, because so far I haven’t seen a good reason to make such a feature easy within the language, creating and using a global counter like this seems like a bad idea to me.

I need a comptime source of globally unique IDs of `comptime_int` type. Global counter is just one way of doing it. It is a pity that Zig or stdlib does not provide any solution.

---

<div class="post-metadata">

**Author:** ![Sze](https://ziggit.dev/user_avatar/ziggit.dev/sze/32/496_2.png) [@Sze](https://ziggit.dev/u/Sze)\
**Post date:** [January 17, 2024, 2:46pm UTC](https://ziggit.dev/t/global-comptime-counter/2874/9 "2024-01-17T14:46:18Z")

</div>

But why do you need such a thing, for what?

I am asking this because I wonder whether this topic is a bit of a [XY problem - Wikipedia](https://en.wikipedia.org/wiki/XY_problem), you said yourself that there are different ways to solve this, if you share the actual problem, without pre-supposing how it should be solved, then maybe somebody has some solution that is way better.
