Worth noting that global constructors and destructors are generally sucky for a bunch of reasons. Don’t use them unless you really have to. Avoid them in libraries.
Reason to avoid global constructors: there’s no laziness to them; they definitely run on program start even if the global is never used. For small projects, no big deal. For large projects it means a large startup time penalty. Successful projects get big eventually, so if you’re playing the long game you want to assume you’re a big project. If you’re a library writer, it’s probable that you’ll be linked into something big. If you don’t have global ctors then your clients will thank you.
Atexit anything is just pointless, IMO. The best way for a process to exit is to just exit. Trying to “destruct” your state at exit risks race conditions and weird bugs but buys you very little. Even things like flushing or syncing a file probably don’t belong in atexit since you should assume your program will run a long time so you want important stuff flushed and synced way before the exit happens. Also, global dtors are implemented by having a global ctor that does __cxa_atexit, so see previous paragraph.
And as with all programming advice, your mileage may vary and some advice is best ignored. If global ctors/dtors achieve what you want and/or startup time isn’t an issue, then do what you feel, bro