It’s common for people coming from other languages that had some sort of abstraction over the encoding to see Zig’s approach as being a problem. However, once those other high level abstractions don’t work for your particular use case, it becomes much worse when you have to figure out how to bypass that abstraction and then re-implement the one you need for your application.
This becomes much worse when you try to use code across external libraries. Most code will be using the default abstraction so if your application can’t, that sometimes means cutting yourself of from being able to use most of the other libraries that exist in the world.
D made the arbitrary decision to always iterate over u8 slices by “unicode codepoint” assuming they are utf8 encoded. However some applications may require iterating over them by grapheme, grapheme cluster or even raw bytes. The trouble is this abstraction not only hides the details you might need to know to write your applications/libraries correctly, it misleads you into thinking everything is simpler than it is and that your code is going to work in more places than it will.
In the end I think utf8/codepoints/graphemes/etc are pretty simple, but they are made to look more complicated than they are as most languages try to hide those details from you.
I’m not sure this is doing what you think it’s doing. The .Windows subsystem is used to tell the linker that the program is a GUI program and therefore no console should be spawned. If this code is working for you, then it’s likely due to the subsystem stuff currently being buggy.