Global variables

Going back and looking at the V programming language my interest was drawn to the fact that it lists "no global variables" as a feature prominently on the web site. Globals are a sore point when programming so what solution could this language have come up with to render them obsolete? Looking at the tetris example code it creates a struct called "Game" at the beginning of the main function that contains all the variables that would normally have been global and then call it's member functions to manipulate them. Of course these member function have full access to the Game struct and so for all intents and purposes the Game struct behaves exactly like a global state to them and I don't see how this approach really solves anything and certainly does nothing for code clarity but it got me thinking about global variables.

Global variables are a problem, they make the code harder to understand and makes multi-threading difficult but people stare themselves blind on the fact that they're global variables and miss the real problem which is the global state of the program that they represent. A global state is something you're going to have and is by it's nature difficult to deal with. Just getting rid of the global variables is dealing with the symptoms and not the problem.
One way you could do it in C that would be similar to the V example is to create a blob struct containing a bunch of variables in the main function and then pass a pointer to said blob along to any function that needed any of its member variables. Which you shouldn't do but is easy to fall into. Sometimes called passing the function "an environment" which I believe is euphemism for "giving it access to a bunch of disparate variables". This would though indicate when a function is using a global because it would take the blob as an argument but it's not fine grained enough to matter. It won't tell you which variable it uses or if it just reads it or changes it. Also since you most likely will end up passing the blob down a chain of functions, just the fact that a function takes the blob as an argument doesn't mean it uses it which moots the whole point.

I don't have any good solution myself but right now I'm thinking about using static variables which in C act just like globals but are only visible inside the code file where they are declared and then use getters and setters. It won't solve any practical problems with the global state but maybe it will make the code look prettier? It would make it more explicit which functions changed their values and which just read them.
There are two things I want to ameliorate by doing this, both having to do with keeping my sloth-like nature in check. First is that when I have arrays as global data structures and need to collate data from them I tend to just plonk down a for loop in whatever function I'm in and iterate through the global array on the spot. Instead I think the code would look a lot nicer if all these for loops were gathered into one code file, even for things that are only used once. When I'm forced to break out those for loops into their own functions this would also give me an incentive to make them recursive which just looks nicer.
Secondly while V doesn't allow global variables it does allow global constants which I'm starting to feel is a cop out.
Often when I start a project I end up hard coding stuff like window resolution out of sheer laziness. So for example I'll have SCREENHEIGHT and SCREENWIDTH as defines because I can't be bothered to think about how I want them stored when all I want is to start working on the actual project. This will then come back to bite me when I have to make it configurable later, even though it's not a huge thing to change.
If instead I had from the beginning made it a habit to always use functions to deliver constants these could much more easily be changed to variables later on if needed and I wouldn't have to think about where to store them, just add a static variable and setter function to the code file. So instead of #define SCREENHEIGHT there would be a function called screen_get_height().

Of course there are some things like pi which are not prone to change and therefore seem suitable to making global constants but even here I wonder if it wouldn't look nicer to have them as functions instead? Having a function return a constant does seem like unnecessary overhead but GCC appears to optimize it away when O2 is used. I don't know assembly very well but it seems these two implementations produce the exact same asm for the main function with O2:

#include <stdio.h>

#define PI 3.14

void main()
{
	printf("mmmmm %f\n", PI );
}
#include <stdio.h>

double pi() { return 3.14; }

void main()
{
	printf("mmmmm %f\n", pi() );
}

The assembly for the function example is a bit longer because it still adds a definition for the pi function but it's never called.
Again this doesn't actually solve any of the problems related to having a global state but for purely aesthetical and ascetical reasons it would be neat to have nothing but function declarations in the global scope. Though you'd still have struct definitions and enums in the global scope I suppose but I would like to get rid of them too.
Maybe this would also force me to think harder over how to structure the code into files and not just dump a bunch of numbers as defines in a def.c file when I don't know where to put them as is my wont.
I think I'm going to try this with the small game I'm making for the tutorial series and see how it pans out. Anyway I don't want to present this as a panacea for how to deal with the program's state or even as a good idea, this is just something I've been pondering lately and it might end up one of those bright ideas that takes you straight off a cliff and makes a mess of the code but either way it should be a learning experience.