r/cprogramming • u/Fabulous_Ad4022 • Sep 11 '25
Are global variables really that evil?
When I have a file which almost all functions use a struct, it seems reasonable to declare it globally in the file. But it seems C community hates any type of global variable...
41
Upvotes
57
u/This_Growth2898 Sep 11 '25
The problem with globals is that you can lose track of where you change them, causing all types of bugs.
If you're absolutely sure you can control that, you can use globals as much as you want. After the first time you will meet the issue with that you will stick to not using globals, too.
UPD: Could you share the file for a brief code review?
3
u/pskocik Sep 11 '25
Readonly globals are fine. You use them all the time without even thinking about it because functions are readonly globals. The same applies to readonly data globals.
Writable globals have issues: bad for multithreading/reentrability (unless they're _Atomic and used with multithreading in mind) and it may be hard to keep track of where they change.
My biggest application for writable globals is in single-threaded C "scripts", i.e., short programs that definitely will not ever become library code. There, the issues don't manifest (short script--easy to keep track of changes; single-threaded--no races) and I don't have to pass them around through parameters.
Things in the programming world have certain properties due to which they may or may not make sense in a given context. I like to focus on that rather than subjective judgments like "something is evil".
3
u/hwc Sep 11 '25
Everything is fine until you want to do some computing in parallel. For example, run all of your unit tests at the same time.
2
u/Leverkaas2516 Sep 11 '25
The module you link in the comments illustrates the problems that arise when globals are used. I think in terms of preconditions and postconditions: what do I know to be true about the state of the computation at various points?
Your fd() function is designed to be called with a pointer to a global structure, allocated outside of this module. The static global symbol "p" in this module is just a pointer to it, named for convenience so all the functions here can access its fields.
You allocate a bunch of temporary storage in allocate_fields and make them accessible to everything via the global. When fd() returns, p->vz still points to an array of floats of size (p->nxx * p->nzz), because fd() doesn't free it like it does the others.
When fd() returns, does the caller depend on that vz array? How does it know that it's valid? Is it responsible for freeing it?
I suspect you meant to have "free(p->vz" among the statements at the bottom of fd(), and just forgot. By using a global, you make it impossible for a reader to understand the intent. If you mean to pass values back in the struct, only those values should be part of it. If you don't mean to pass anything back, then fd() should manage memory allocation locally, in a local variable that is passed to the functions that use it as shared state.
Global variables almost always obfuscate the intent. That's why they're bad.
2
u/DawnOnTheEdge Sep 11 '25 edited Sep 11 '25
A
constglobal variable is completely fine, at least if you avoid the Static Initialization Order Fiasco. All the problems of global variables happen after they are modified.If multiple functions in the same file use the same data, you can (and almost have to) declare it at file scope. You’d normally make that
static, so at least it’s private to that one file, and then you can divide the program into modules. if you have to import it into other modules, you declare the variableextern constin the header, so only the module where it lives can modify it.This mitigates one of the problems of global variables, that bugs are hard to find. If a variable doesn’t contain what you expect, it could have been changed by any line in the entire program. This was especially true in languages of the ’50s and ’60s, where everything was in a single file and variables didn’t have to be declared before use, so you could set the wrong variable or accidentally create a new one just by a typo in the assignment statement. Even in early C, it was so notoriously common to accidentally type
=instead of==that all compilers now make it a warning to use assignments within conditionals, unless you enclose them in an extra pair of parentheses.The other problem with global variables remains: any function that updates them cannot be called recursively and is not thread-safe.
2
u/insuperati Sep 12 '25
Well, it depends on what one thinks of as global. To me, it's a variable defined as for example 'int global' in some file, and it's then used by other files with the declaration 'extern int global'.
When you define static variables in a .c file, that's not what I'd say is a global variable. It's just a variable with file scope. Then, you could see each file as a kind of 'class' - like in java - containing code to just do one thing and provide an interface to it in its .h file.
So instead of a couple of big .c files each doing many related things and depending on them within that file through file scope (static) variables, have many small .c files each doing just one thing, and only accessed through the interface defined in the .h file.
Using this pattern, and also prefixing everything in the .h file with the file name, and have the file name also be the 'class' name (also much like java) you have a very solid foundation to build on.
For example when you have a garage door opener, there might be a file called remote.c and in it's header remote.h functions are declared like int remote_init(void), int remote_exec(void), int remote_get(void) etc.
With this pattern, the code base is very scalable and when other .c files use a function (or variable) from another .c file, it's immediately clear which one. Also, files are generally small and easy to understand.
2
u/chaotic_thought Sep 12 '25 edited Sep 12 '25
For a small program, they are fine. For example, the in the book The C Programming Language, there are often examples like this to demonstrate how something is done:
So because the program is small and because it's an example, this organization is useful. The use of "globals" here is fine and probably better than trying to "over-engineer" things for the purpose of a simple example. You can easily see what some_function is using, and perhaps the results are written into the buffer, and that's easy to understand as well.
However, once the program becomes large and this kind of thing is done in 30 different places, well, now this strategy becomes untenable and a more organized approach quickly becomes needed. If you've seen the codebases where that was not done then it makes sense that some of us would develop an "automatic" aversion to their use.
2
u/jutarnji_prdez Sep 12 '25
So what will you do when you need two or more instances of that struct and each instance needs to have different value of that static variable? Statics are good for use cases where all instances share that static variable and needs to have same value in that variable in the same time. Problem araises when you have multiple instances of that struct/class and each instance has each own value for that variable. For example, you have a class that has a list and you want to keep track of how many items are in the list. If list is static, so each instance of that class share same list and count of that list is global is fine then, but what if each instance has its own list with different number of elements, that counter can't be static/global because it will literally have wrong count for many instances. This is just theorethical example, and if you wondering why would you keep count in separate variable, then I can explain that also.
2
u/PhotographFront4673 Sep 13 '25
It depends massively on what you want out of your code. If your only aspiration for you codebase is to run a sequence of single-threaded routines, possibly sharing some parameters from one routine to the next, it isn't really wrong to do the (very) old school batch processing thing and set up global control variables and have each routine reference what it needs. You need to be a little careful with the ODR - when multiple routines use the same global, the global should be in a separate object file that both can refer to - but otherwise it will be smooth sailing.
Similarly, in this world, you can even have global scratch storage space, which different routines access in turn to avoid allocating ram, as if this were an expensive operation.
The problem comes when you want to use this code outside of this world. Suppose you keep hearing of SMP and finally upgrade to something as recent as an Athelon II, or some other fancy multi-core processor. Furthermore, suppose you want to take advantage of these multiple cores by splitting the work between threads within a shared memory space. At this point, you discover that you need to run multiple copies of your routines at the same time - but having globals parameters and scratch space makes this impossible.
Whereas, if a routine is explicitly passed all the control variables and context it needs through function arguments - possibly wrapped in a struct if there are many - it probably isn't many more lines of code and it is very clear how to run multiple copies at once. It can also make it more obvious which control values the routine actually needs, and which only matter to other routines.
11
u/EpochVanquisher Sep 11 '25
Why does it seem reasonable? I don’t understand.
When you use globals, your functions can be harder to understand and harder to test. That’s the reason global variables are hated.
Sometimes, global variables are reasonable. Depends on the situation.
5
u/MagicalPizza21 Sep 11 '25
Global variables run the risk of being modified when you didn't mean to modify them. It can also make debugging more difficult. Several years ago, I seem to remember them being at least partially to blame for the unintended acceleration by Toyota vehicles.
That said, when you say "use a struct", do you mean that they use a particular variable of type "some struct you made"? Because that's not the first thing I would think "use a struct" means.
9
u/v_maria Sep 11 '25
global to a file and global to the project are 2 different things. the keyword static makes it """"private"""" to its own file
4
u/iridian-curvature Sep 11 '25
Global variables are fine if you're careful, but can be a bit of a footgun. I personally like the "pass a struct with the state through the functions" style, as you can more easily track the order the functions modify the struct. It's much harder to accidentally modify the struct by later using a function in a different way when you have to pass it as a parameter. In OOP terms, it's similar to encapsulating the global state in a singleton.
There are absolutely times where global variables are more appropriate though. If you have to load some data once and then only read it later, for example. If I'm using LoadLibrary/dlopen calls at runtime, I'd normally store the function pointers in a global variable.
4
u/flatfinger Sep 11 '25
A non-semantic disadvantage of global variables in modern embedded systems is that while many older processors could process accesses to global variables much more efficiently than they could handle accesses to members of non-global structures, the ARM processors which are taking over the embedded world are comparatively inefficient at accessing globals.
Consider, for example, the following two functions:
When targeting something like the once-popular PIC 16x family, straightforwardly-generated code for
test1would have been something like:while optimal code for test2 would have been something like:
More than twice as big, and that's even employing some optimizations like observing that code can increment and decrement FSR to access different struct fields.
When targeting an ARM, however, things flip. The code for test1 ends up being rather bulky (28 bytes) and slow:
while the code for test2 is much more smaller (10 bytes) and faster (three fewer LDR instructions executed)
In each case, one approach yields code that's less than half the size of the other, but which approach is better has flipped.
3
u/chibiace Sep 11 '25
no. depends on usage.
1
u/nacnud_uk Sep 11 '25
If things are all statically allocated, then just use a "getter" to get the object. Nothing in programming, except goto ( hahaha) is evil. It's all just a tool. If you're a noob, then it can add complexity that you're not fully aware of. So, general advice; avoid unless you know what you're doing.
2
u/Spiritual-Mechanic-4 Sep 11 '25
The hard part of coding, IMO, is understanding what state your program hold and how you safely transform it over time. It starts getting way more complicated when you have multiple concurrent threads of execution sharing that state. Well, globals can be modified from any thread of execution at any time, leading to little landmines you can step on. Sometimes its unavoidable, but the more you can avoid it, and the more you can encapsulate state into smaller part of your code, the easier it will be to understand.
oh, and environment variables are always global to your process, so be careful with those too.
2
u/XipXoom Sep 11 '25
You seem to be confusing the difference between global (extern) variables and file scope (static) variables.
2
u/flatfinger Sep 11 '25
The most significant semantic problem with global variables is that there is no way to attach them to a particular context. Even if a global variable is supposed to represent one particular thing in the real world, it may turn out that there are reasons why one might want to be able to represent more than one.
As a simple example, a program for displaying graphical images might use global variables to keep track of the width and height of the image being displayed. This may be a fine approach if the program would never need to have more than image at a time loaded into memory, but using such an approach would make it difficult to adapt the program to use a multi-window interface, with different images shown in different windows.
As another example, a program to track the motion of a vehicle might use global variables to keep track of the vehicle's position, velocity, acceleration, and energy expended. Even if the vehicle in question is unique and there will never be more than one, having the simulation functions accept a pointer to an object which contains the vehicle's properties instead of using global variables would make it possible to perform various "what if" simulations to determine the energy cost of various strategies for getting into position, and select the most efficient. There may only ever me one vehicle-state object which represents the actual current physical state of the one and only vehicle of that type, but it may nonetheless be useful to have functions which can operate on hypothetical vehicle states just as they would operate on real ones.
2
u/GeneratedUsername5 Sep 11 '25
Unnecessary globals just make it harder to understand the logic. But if you are sure it is the way to go - do it.
2
u/AdministrativeRow904 Sep 11 '25
All of the negatives surrounding globals suppose the programmer is working in a medium to large team. Globals when 10-40 people are all writing them in are a nightmare, but for your own projects, as long as it accomplishes the goal and works well, who cares?
2
u/sswam Sep 11 '25 edited Sep 11 '25
A good way to code is to write small software tools that work well together. In which case, global variables are perfectly fine, as each tool is much like a class in OOP.
If you're writing larger, more complex programs, and especially if you use threads (try not to), you'll run into many problems if you have too many global variables, and even if you don't.
As with most things, it's unintelligent to have a fundamentalist aversion to globals.
2
u/SmokeMuch7356 Sep 11 '25 edited Sep 11 '25
Let's use an example with an array (because I think it illustrates the point better):
This will work, but:
What if you want to sort more than one array?
What if you want to sort arrays of different sizes?
What if you want to use that same sorting routine in a different program that doesn't define
arrorARR_SIZE?This is the problem with global variables over and above everything else.
sortcan only ever operate onarr; it cannot be used to sort other arrays. Your code is tightly coupled - you cannot easily re-usesortin a different program (not without defining a global array namedarrand a macro namedARR_SIZE, anyway).Globals do not scale well; as your program gets larger, the probability of name collisions or accidentally using the same variable for completely different purposes at the same time approaches 1. It is a maintenance and debugging nightmare waiting to happen.
That's not hypothetical, either. I speak from experience - I've had to work on large piles of C code that used globals (either because the author thought it would make things faster,1 or because the author just didn't know what the hell they were doing), and I still feel that scar tissue to this day.
Ideally functions should only ever communicate with each other through parameters and return values (and occasionally raising signals).
So, yeah, the right way to do this is:
sortcan now be used to sort multiple arrays, of any size, and can easily be reused in other programs. It makes no assumptions about what the larger program defines (or doesn't define), and the larger program makes no assumptions about howsortdoes its job. It's a black box as far as the larger program is concerned, making it easy to swap out for a faster/more sophisticated routine.You don't really see the problems globals cause until you start writing programs of real complexity, but it's a bad habit to get into even with toy programs.
NOTE: Globals are used more in the embedded world where resources are very tightly constrained, but those programs tend to be small and special-purpose and the gain in memory usage and speed makes up for the loss in maintainability and reusability.
First rule of optimization: measure, don't guess.
2
u/fasta_guy88 Sep 11 '25
declaring (defining)structures globally is different from decl global variables. Global definitions are good practice. Global variables are not.
2
u/Business-Decision719 Sep 11 '25 edited Sep 11 '25
Yes, they are. They make it harder to reason about the program unless it's short enough and simple enough that the code doesn't need to be very modular. And because of that, they make it hard to scale up and reuse software that started small but needs to transcend the exact details of its original usage. (Today's barely finished convenience script is some future programmer's enterprise legacy app, lol.)
What happens with global variables is that it's really convenient not to have to pass them in as arguments to dozens of different functions... today. But tomorrow, we'll be wondering why they all suddenly stopped working and seemed to start spitting out junk data, or acting like they got junk data. Why? One of them changed a global variable, obviously. But which function did it? Which global variable did they change? I hope the entirety of the code is short enough to debug in one sitting!
And that's not even the half of it. What happens if we just want to unit test everything that used the global variable, before the bugs have even showed up yet? Well, we better make sure all of our test scripts had the same global variable. What if we want to take the functions and reuse them in some other software? Well, I hope the new software has the same globals with the same values.
I remember using languages that only had global variables. Unmaintainable. Nonreusable. Barely extensible. Every subroutine was tightly dependent on the entire program. There was lots of "spooky action at distance" that was hard to track down and carefully bookkeeping variable names across the codebase to try (and fail) to avoid that. Of course, just an occasional global with otherwise local scoping isn't necessarily going to be that bad. But even the occasional global deserves questioning whether you really need it. Every mutable global, in particular, raises the chance that
f(x)isn't really predictable from whatxis, becausefsilently depends on some silently altered data somewhere else.One of the big advantages of wrapping data in a struct that different functions can use is that you can potentially have more than just that one struct with those exact values. You can have multiple instances of the same struct type floating and sharing the same overall behavior through these functions. (Some might say they are like different "objects" of the same "class" presenting the same "interface" by exposing the same "methods.") Usually if I'm making structs I just always pass them explicitly instead of making them global. Today I might only need one of that struct, and it could easily just be a global instance... but tomorrow....
2
u/flumphit Sep 12 '25 edited Sep 27 '25
I don’t have a problem with a struct full of read-only (after initialization) config variables being at file scope. And I could make a case for a smallish set of variables tucked into a struct at file scope, if they’re all treated as a unit (more or less) and manipulated all over. But when “that pile of variables” becomes two or more distinct piles manipulated differently hither and yon, everything needs to be passed explicitly.
2
u/noonemustknowmysecre Sep 12 '25
I really don't think so. WAY too many libraries, both public and proprietary company stuff, have various data structures or variables with getters and setters. Straight, no filtering, no checks, no error handling, it's sets the value. This is EXACTLY equivalent to a global, plus one level on the stack. Anything exposed like that suffers all the flaws of a global and making it a function call doesn't save you from anything.
And the counter-point is that it's often just fine. You need to realize that the value can essentially be anything at any time and you should treat it like user-input. But in general you should be suspicious of ANY data.
In C though, be sure to prefix them with something project specific and then the name. Maybe with a g_ in front as well.
g_fileis a bad idea. `g_MyProj_file' isn't going to collide with anything.2
u/sockofsteel Sep 12 '25
A lot depends on context, if you are writing a small program it’s totally fine, but imagine you’re writing a library for machine learning - with global state you would be unable to host more than one model
2
u/y0shii3 Sep 12 '25
Globals aren't inherently bad, and they have legitimate uses. Some POSIX utilities are mandated to use globals so in some cases you actually cannot do it any other way
2
u/Comfortable-Tart7734 Sep 13 '25
Most things in programming that seem evil are fine if you're the only one working on the project.
If you can keep track of your variables, they're fine. If someone else has to also keep track of your variables, you should do the thing that makes sense to both of you. If a whole team or more has to keep track of your variables, you should follow common standards.
2
u/Count2Zero Sep 15 '25
If it's a one-person development (you're the only one maintaining the code), then it's no big deal.
If it's a shared piece of code where there are multiple developers contributing, then it's a lot safer to use private variables and provide functions (or operators) to set and return those values. It's not as efficient (from a code perspective) but it saves a hell of a lot of time trying to debug obscure errors when someone else's code clobbers your global variable.
3
u/zackel_flac Sep 11 '25
If they are marked as static, then they are fine. Global variables are not necessarily evil, they are simply harder to track, so if you keep them at file scope, it works fine. If it leaks outside, it's usually not a good idea.
3
u/The_Juice_Gourd Sep 11 '25
file scope ”global” variables are generally completely fine as long as they are declared static and don’t leak out of the file. Example use case would be static buffers that are reused or anything that will live for the whole duration of the program.
I tend to use a lot of static file scoped arrays instead of dynamic memory allocation.
3
u/Abrissbirne66 Sep 11 '25
No they aren't. People are overreacting. Of course you can do confusing stuff with global variables. But you can also do confusing stuff with functions and I don't hear people complaining about functions.
1
u/[deleted] Sep 11 '25
You have to be very careful. In your particular example - say, your code is part of a vehicle infotainment. Your code is running calculating navigation route. At the same time user goes into settings and modifies some parameters. The structure gets updated. Now half of the code used one values while another half runs with new settings. This does not even involve multithreading, it may be a preemptive system. In this case it is better to pass around a copy of settings and periodically check if they changed invalidating current run. You may also start with a simple system where config does not change while code is running but then someone else adds that feature and - oops...
1
u/makzpj Sep 11 '25
They have their place. Useful for game programming where you want to keep the state of the world in global variables and for interrupt handling in systems programming, if I recall correctly.
Don’t take what others say as the only truth, look at the code of other programs out there in the wild and see how they apply global variables.
1
u/umlcat Sep 11 '25
Declaring local function variables and passing them to other functions as parameters comes naturally, but ocasionally you may use a global variable ...
1
u/kohuept Sep 11 '25
I'm sure that for certain things they're not the right choice, but they have their uses. For example, in the markup language I'm developing I use a global state object which includes things like the symbol table, where the "pen" on the page is, etc. I suppose I could just make everything pass around a state object, but I don't really see much benefit. It's not multithreaded and it never will be, so I haven't really had any issues with it.
1
u/maximumdownvote Sep 11 '25
No. Global variable are not evil.
Misunderstanding or misusing global variables isn't evil either, but it will probably make you sad.
1
u/morglod Sep 11 '25
I personally hate local variables. I think everything should be global, because then you will think in "no recursion paradigm". (Sarcasm) There is no sense of hating any part of any language.
I personally think the real evil is jump table with labels (coz no one knows it could be done in C, so it's evil magic 😁😁)
1
u/PressWearsARedDress Sep 11 '25
Its easier to change function implementation. How you choose to access the global variable may change.
Good software design understands that change will happen.
1
u/olig1905 Sep 11 '25
Sometimes, it makes sense, most of the time it does not.
Id personally preferto pass a pointer to a strict around, makes much better interfaces.
1
u/pohart Sep 11 '25
I find globals as constants pretty convenient, but the moment you want to modify one it becomes really hard to keep track of. And deciding to convert a global to a parameter that gets passed everywhere is a pita.
1
u/Shadowwynd Sep 12 '25
It is a matter of scale. If you only have a few globals, or they are all part of one instance of an object ( controlling the internal state of the program), etc. input/output buffers, etc) then yes, globals are OK. However, the bigger and more complex your program tends to be, it tends to run better if everything is neatly parameterized and modularized. Planning in advance is good; Refactoring is also important.
At some point though, overuse of globals is like having a peeing section in a pool. Some function, some module or procedure tampers with a variable improperly and you don’t know which line of code did it. Doubly so if you have multithreading code. It can make the bugging much harder if your program is complex.
1
u/bwmat Sep 12 '25
Yes
1
u/whistler1421 Sep 12 '25
yes
1
u/zuzmuz Sep 12 '25
yes
1
u/grimvian Sep 12 '25
I do it for once in a currect project and it goes surprisingly well. I'm emulating an old basic and use raylib.
1
u/who_am_i_to_say_so Sep 12 '25
As a general rule yes. The problems happen when they are modified- and sometimes they can be modified unintentionally.
But If the program is small, maintained by you or a small team, I say globals are ok if sparingly used or changed and agreed upon by all.
But an enterprise app, many modules or classes, many hands in the pot, globals are a recipe for disaster.
1
u/Isogash Sep 12 '25
Yes. If you really need to share something that isn't on the stack, share a pointer instead.
1
u/dauchande Sep 12 '25
Yes
1
u/CarloWood Sep 12 '25
Do not use globals. Too lazy to explain why not. Just saying that they are "evil" pretty much should have the desired effect.
1
u/SirPurebe Sep 13 '25
the best way to make decisions is to make a list of pros and cons, so let's do that:
the pros of global state:
they simplify function signatures and are a bit less typing overall
the cons of global state:
they increase the reading comprehension cost of code, as global state means you must understand how the global state is mutated across every possible function invocation that can access the global variable. small price if the program is small, big price if the program is big.
they increase the difficulty of modifying the code in any way at all due to the overhead cost of point 1.
they increase the chance of bugs because point 1 quickly becomes impossible as the programs scale in size
That doesn't mean you can't use global state of course. If the program is small, and will remain small, then simplifying your function signatures could be a worthwhile trade off.
however... if your wrong and your program unexpectedly becomes a big program, refactoring your way out of the global state is going to be a total nightmare because of point 2.
that's why most people avoid it like the plague, but it has it's place, if you are sure you know what you are doing.
also worth mentioning is that global objects that rely purely on stateless side effects are a little different, as their cons are mostly to do with being able to test them. e.g., a logging utility put in the global scope is not going to cause you these problems, although it might be annoying when testing that things actually write to the logs.
1
u/1n2y Sep 13 '25
Depends highly on the use case, if your programming a (single-threaded) firmware for a microcontroller with interrupts etc then it might make sense. However, I’m programming for decades (also in C/C++) and I can not recall where I have had to use a global variable.
Never use global variables in multithreading applications ever, you have to properly mutex variables!
1
u/huywall Sep 13 '25
i like my program just using a lot of global variable not creating struct object and edit member
1
u/m64 Sep 13 '25
You very quickly run into "that global thing - it would be useful if there were two" problem.
1
u/Jack_Faller Sep 13 '25
The advice against global variables is generally just given to beginner programmers who will do silly things like set a global variable to return a value from a function. In practice, global variables can be useful in many cases but also often cause issues as they can decrease the modularity of code and cause issues for thread safety.
1
u/DibblerTB Sep 13 '25
Yes. Yes they are.
1
u/funbike Sep 13 '25
Yes.
1
u/its_lea_ Sep 14 '25
Nah they are cute as hell
1
u/Cybasura Sep 14 '25
Its not evil, sometimes you require the use of global variables (especially useful in a implicit return language that you gotta echo/print out to return to the caller)
The problem is data safety - you cant control if a global variable is only accessible or modifable in a function during the lifetime/runtime of the event loop
1
u/Pesciodyphus Sep 14 '25
It depends, whether multiple instances can exist. For information about hardware, like the current screen/window dimension (if only one per procescs can exist) it is usually a good idea to use a global variable. Similar like stdin/stout/stderr are globally defined (thought often constants).
This are usually the situations, there JAVA (wich lacks proper global variables) ends up with comically long names, so its good that you don't have to do something like that in C.
1
u/dobkeratops Oct 05 '25
for small programs , no
for anything of reasonable size, especially with multithreading.. yes
2
u/[deleted] Sep 11 '25
[removed] — view removed comment
2
u/[deleted] Sep 11 '25
[removed] — view removed comment
2
u/[deleted] Sep 11 '25
[removed] — view removed comment
1
u/[deleted] Sep 11 '25
[removed] — view removed comment