Author Topic: Global variables - Evil or not  (Read 7542 times)

0 Members and 1 Guest are viewing this topic.

Offline JesterTopic starter

  • Frequent Contributor
  • **
  • Posts: 859
  • Country: ca
Global variables - Evil or not
« on: October 20, 2022, 05:47:08 pm »
Context:
1) I'm not a programmer I just dabble in C and c++ to a small extent.
2) Embedded application running on a smallish uC for example a small sub module in a automobile, for example: bool wipersOn = false;

I appreciate a global variable in some large program for some large company for example American Airlines would probably be a really bad idea.

The moment you google "global variable" half the comments are DON'T DO IT you will burn in hell.

I have used global variables forever and have never had any issues. Am I missing something?
 

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: Global variables - Evil or not
« Reply #1 on: October 20, 2022, 05:58:48 pm »
most of my global variables are actually global so that i can inspect them at any time (so are declared global for convenience)
a little few are actually global so they can be accessed easily, but they always are written by one process, read by many... or the processes that can perform a write are not preempted so there is no chance that two writes happen simultaneously.

The problem as i understand it is when the global variable is read while it's being written too, or it can be written by two or more actors. Especially if the read/write is not atomic (think reading/writing 32bit on a 8/16 bit machine) If you can make it sure that it doesn't happen, then no issue for me.
the DON'T DO IT is because too many programmers don't understand this simple concept (with not so simple consequences)
And writing accessory functions can have other benefits as well, such as including the range check for the new value

Some times you cannot escape from globals anyway (shared memory, memory at fixed locations, ...)
 
The following users thanked this post: Jester

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11653
  • Country: my
  • reassessing directives...
Re: Global variables - Evil or not
« Reply #2 on: October 20, 2022, 06:03:28 pm »
Context:
1) I'm not a programmer I just dabble in C and c++ to a small extent.
I have used global variables forever and have never had any issues. Am I missing something?
yes you are missing something... try to program a little bit larger. for example try to create a Windows GUI library for embedded MCU handling lots of messagings, events, interrupts etc. i recommend do it for PC where you can program larger all you like at virtually unlimited resources. at one point as your program grows and need maintenance and bugs fixes, you'll see why. this rule doesnt apply to small program. the devil is actually in yourself, it hasnt come out yet. if you can appreciate why people invented OOP (and modular subroutines much earlier) you will understand why. its quite difficult to explain to you in short sentences what an elephant is when you havent seen one.
« Last Edit: October 20, 2022, 06:08:30 pm by Mechatrommer »
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline JesterTopic starter

  • Frequent Contributor
  • **
  • Posts: 859
  • Country: ca
Re: Global variables - Evil or not
« Reply #3 on: October 20, 2022, 06:05:48 pm »
Context:
1) I'm not a programmer I just dabble in C and c++ to a small extent.
I have used global variables forever and have never had any issues. Am I missing something?
yes you are missing something... try to program a little bit larger. for example try to create a Windows GUI library for embedded MCU handling lots of messagings, events, interrupts etc. at one point as your program grows and need maintenance and bugs fixes, you'll see why. this rule doesnt apply to small program. the devil is actually in yourself, it hasnt come out yet. if you can appreciate why people invented OOP (and modular subroutines much earlier) you will understand why. its quite difficult to explain to you in short sentences what an elephant is when you havent seen one.

If you are going to quote me, please don't selectively hide the part of the quote that applies to my question.

Context:
1) I'm not a programmer I just dabble in C and c++ to a small extent.
2) Embedded application running on a smallish uC for example a small sub module in a automobile, for example: bool wipersOn = false;
« Last Edit: October 20, 2022, 06:08:18 pm by Jester »
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11653
  • Country: my
  • reassessing directives...
Re: Global variables - Evil or not
« Reply #4 on: October 20, 2022, 06:11:47 pm »
i dont quote what is irrelevant. or what that doesnt make any difference from the important fact that you are working on small system (or just working). so less chance for you to wander, we encountered such situation may times. but if you dont like my comment, just ask to delete it i will gladly do. you can get what you are missing (or not missing at all) from somebody else.
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11269
  • Country: us
    • Personal site
Re: Global variables - Evil or not
« Reply #5 on: October 20, 2022, 06:13:46 pm »
There is nothing wrong with use of global variables where justified. And in small embedded systems it is justified a lot.

2) Embedded application running on a smallish uC for example a small sub module in a automobile, for example: bool wipersOn = false;

In automotive environment it is a bit harder, since you will also start running into MISRA-C limitations. MISRA-C recommends to avoid global variables and make sure that the variables are declared in a scope that minimizes their visibility. But if you build your application around global variables, then global visibility becomes necessary.
Alex
 
The following users thanked this post: Buriedcode, Jester, SiliconWizard

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19522
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Global variables - Evil or not
« Reply #6 on: October 20, 2022, 06:28:58 pm »
If you are going to quote me, please don't selectively hide the part of the quote that applies to my question.

Context:
1) I'm not a programmer I just dabble in C and c++ to a small extent.
2) Embedded application running on a smallish uC for example a small sub module in a automobile, for example: bool wipersOn = false;

Such selective quoting seems to be happening more frequently on this forum at the moment. It is often accompanied by strawman arguments deployed for a variety of reasons. IMNSHO such tactics should be called out for what they are, lest too many contributors think it is acceptable.

IMNSHO the alternative is to allow conversations' value to be degraded, and hence to the degradation of the overall utility, civility and friendliness of this forum. That would be a pity.

N.B. mechatrommer's specific post snipped because I am making a more general point than that specific post.
« Last Edit: October 20, 2022, 06:30:44 pm by tggzzz »
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 
The following users thanked this post: Jester

Offline magic

  • Super Contributor
  • ***
  • Posts: 6783
  • Country: pl
Re: Global variables - Evil or not
« Reply #7 on: October 20, 2022, 06:48:25 pm »
I have used global variables forever and have never had any issues. Am I missing something?
Yes, dependency injection :D
 
The following users thanked this post: T3sl4co1l, Jester, paulca

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11653
  • Country: my
  • reassessing directives...
Re: Global variables - Evil or not
« Reply #8 on: October 20, 2022, 07:15:09 pm »
Such selective quoting seems to be happening more frequently on this forum at the moment. It is often accompanied by strawman arguments deployed for a variety of reasons.
he's asking something that is not his problem. when in small uC people talk about global variable go to hell? is like asking "people said using roger laminate pcb is better than FR4. i've been using FR4 with my small arduino fine, whats i'm missing?" and if someone posts 999 lines of irrelevant/useless statements and only one of related/usefull point of interest, should we quote/duplicate all 1000 lines of almost all useless points? where is the "doing more, with less"? ;D
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 
The following users thanked this post: WattsThat

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19522
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Global variables - Evil or not
« Reply #9 on: October 20, 2022, 07:27:06 pm »
Such selective quoting seems to be happening more frequently on this forum at the moment. It is often accompanied by strawman arguments deployed for a variety of reasons.
he's asking something that is not his problem. when in small uC people talk about global variable go to hell? is like asking "people said using roger laminate pcb is better than FR4. i've been using FR4 with my small arduino fine, whats i'm missing?" and if someone posts 999 lines of irrelevant/useless statements and only one of related/usefull point of interest, should we quote/duplicate all 1000 lines of almost all useless points? where is the "doing more, with less"? ;D

He stated accurately accurately the context which he felt should have been included.
I copied that context.
You have omitted both.
You have made a completely different point which isn't relevant to that.

You have therefore again omitted relevant context.
You have therefore again raised a strawman argument.
And that is despite my specifically stating that I was making a general point, not a specific point about your post.

Remarkable.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 
The following users thanked this post: Jester

Offline MikeK

  • Super Contributor
  • ***
  • Posts: 1314
  • Country: us
Re: Global variables - Evil or not
« Reply #10 on: October 20, 2022, 07:27:16 pm »
If you're not using that much RAM in your application there's no reason to limit your globals.  You need to avoid globals when memory use and management become an issue.  If you're fine with using globals, keep doing it until you run into problems.
 
The following users thanked this post: Jester, jpwolfe31

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11653
  • Country: my
  • reassessing directives...
Re: Global variables - Evil or not
« Reply #11 on: October 20, 2022, 07:36:37 pm »
He stated accurately accurately the context which he felt should have been included.
everybody can read his context... and here again if i want to make more into context so it can be clearer to you (i dont have to duplicate contexts that have been duplicated many times)..

The moment you google "global variable" half the comments are DON'T DO IT you will burn in hell.
you see, he have his stated context at the top, and then he claimed he googled, and found something that is weird. i highly suspect the answer he got from google are for entirely different context (or from some clueless posters). not for his specific context. prove me wrong. i gave you analogy (about Roger vs FR4 in case you missed that).
« Last Edit: October 20, 2022, 07:38:32 pm by Mechatrommer »
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14490
  • Country: fr
Re: Global variables - Evil or not
« Reply #12 on: October 20, 2022, 08:09:14 pm »
As with anything else, the crux of the matter is not whether you should or should not use them, but why, how and when.

Since "DON'T DO IT you will burn in hell." doesn't answer any of that, you guessed it right, it's useless.

To start the thought process, you must begin with the distinction between declaring globals for the static allocation of state data and *accessing* globals directly in functions without passing them around as parameter. The two are orthogonal, yet many, especially beginners, will confuse the two in nice chunks of spaghetti code.

- For the former, one way or another you will have to use global variables, unless you are OK with using dynamic allocation on the heap (which is usually not a good idea at all on small MCUs) or maybe even on the stack (for instance, if you allocate local variables in your main() function to store global state, why not - it may just unnecessarily eat up stack space which is usually very limited on small MCUs.)

- For the latter, you can absolutely use global variables while limiting a direct access to them to the very bare minimum and otherwise passing them as parameters to functions, or pointers to them. This is by far the preferred way of doing it unless you like spaghetti. (It's good as a dish, not so much for software.) Doing that will tremendously help 1/ maintaining code and making it scalable, 2/ verify and validate code.
 
The following users thanked this post: Jester

Offline AndyBeez

  • Frequent Contributor
  • **
  • Posts: 856
  • Country: nu
Re: Global variables - Evil or not
« Reply #13 on: October 20, 2022, 08:12:22 pm »
For 'production' programming - in any language - you should be thinking about keeping your variables in some kind of Data Structure. A data structure acts like a master collection of variables with global scope.

Defined either as an array, or a class with getter and setter methods, a data structure is a means of storing values so they can be used by the run time, but keep them together in their own memory bear pit. 

In your example, the wiper control function might access Vehicle.Wippers.Speed or Vehicle.Wippers.Clean. The lighting control function uses Vehicle.CabLight.Mode. But every value is inside the Vehicle global class. Whether these individual values are Booleans, Strings, Numerics, Enumerations - or even whole functions - that's up to you.

For code maintenance, holding values in an organised data structure, rather than a splurge of local and global scopes variables referenced by *&pointers, makes for adding and subtracting values a lot less than evil >:D

 
The following users thanked this post: Jester

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19522
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Global variables - Evil or not
« Reply #14 on: October 20, 2022, 08:29:01 pm »
He stated accurately accurately the context which he felt should have been included.
everybody can read his context... and here again if i want to make more into context so it can be clearer to you (i dont have to duplicate contexts that have been duplicated many times)..

... and there you go again.

'Nuff said.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 
The following users thanked this post: Jester

Offline RoGeorge

  • Super Contributor
  • ***
  • Posts: 6207
  • Country: ro
Re: Global variables - Evil or not
« Reply #15 on: October 20, 2022, 08:33:29 pm »
Am I missing something?

Yes, but not about programming, it's something else much deeper:
There is no such thing as (standalone) Good or Evil.

These concepts of Good and Evil only makes sense in relation to a goal.  What helps with the given goal is considered Good, what stands against is Evil.  What is Good for one can be Evil for other.

About global variables, if they help your code, they are Good, if they create problems, they are Evil.

Sometimes they are considered bad practice because people often forget about them, or are not told about them (in bigger projects) so they reuse that variable name, and thus they create a mess hard to debug.

In embedded programming, where each byte and each clock cycle counts, and where the stack memory is usually very small, the tale about global variable is quite contrary:  Global variables are preferred, because they can make the code shorter and faster.
« Last Edit: October 20, 2022, 08:38:39 pm by RoGeorge »
 
The following users thanked this post: Jester

Offline coppice

  • Super Contributor
  • ***
  • Posts: 8654
  • Country: gb
Re: Global variables - Evil or not
« Reply #16 on: October 20, 2022, 08:36:27 pm »
Global variables easily become a religious issue, like many programming topics. There is nothing fundamentally wrong with global variables. Some things really are truly global, and there is no point in treating them any other way. Things you initialise at startup, and will never change during the runtime of the program, have no reason to be treated as anything but global variables. The problems come not from their use, but their overuse.
 
The following users thanked this post: Jester

Offline langwadt

  • Super Contributor
  • ***
  • Posts: 4436
  • Country: dk
Re: Global variables - Evil or not
« Reply #17 on: October 20, 2022, 08:45:34 pm »
Global variables easily become a religious issue, like many programming topics. There is nothing fundamentally wrong with global variables. Some things really are truly global, and there is no point in treating them any other way. Things you initialise at startup, and will never change during the runtime of the program, have no reason to be treated as anything but global variables. The problems come not from their use, but their overuse.

yeh, all the IO and peripheral registers are global ..
 
The following users thanked this post: Jester

Offline CatalinaWOW

  • Super Contributor
  • ***
  • Posts: 5239
  • Country: us
Re: Global variables - Evil or not
« Reply #18 on: October 20, 2022, 10:43:11 pm »
A simple example shows how many rabbit holes this question can dive into.  Take one of the physical constants.  Pi.  Seems like a perfect candidate for a global level.  There are languages in which is made available as a language define value.  There shouldn't be any issues with someone writing while someone else is reading.

But dig a little deeper.  Some parts of your application may need full double precision or greater.  Others want want less for speed or memory efficiency, or even just to assure consistency with another source.  I have even seen applications where using integers and the 22/7 approximation makes sense.  If any or all of these happen the benefit of global application diminishes and may go negative.

 
The following users thanked this post: Jester

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4040
  • Country: nz
Re: Global variables - Evil or not
« Reply #19 on: October 20, 2022, 10:57:26 pm »
Context:
1) I'm not a programmer I just dabble in C and c++ to a small extent.
2) Embedded application running on a smallish uC for example a small sub module in a automobile, for example: bool wipersOn = false;

I appreciate a global variable in some large program for some large company for example American Airlines would probably be a really bad idea.

The moment you google "global variable" half the comments are DON'T DO IT you will burn in hell.

I have used global variables forever and have never had any issues. Am I missing something?

There are two different issues:

1) static lifetime for a variable. This is absolutely necessary for statefull programming. Sometimes these variables may even need to be in EEPROM rather than RAM so they survive reset/power off.

2) too much visibility of a static variable, such that you can't easily know which parts of the program read and/or write to it.

Tools such as an IDE or even simply grep on the command line can help you find all the places a variable is used.

If a variable is used in a single function then it can be declared as "static" inside that function.

If a variable is used in a small number of functions then it and those functions can be gathered in a single C file and the variable global in that file but  marked as static. Other C files will then not be able to refer to it by accident.


In a small program none of this is a problem. The potential problems arise in large programs with poor modularity discipline.
 
The following users thanked this post: Buriedcode, Jester

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21698
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: Global variables - Evil or not
« Reply #20 on: October 20, 2022, 11:25:10 pm »
0. It doesn't matter, everything goes, it's C, do whatever you like!

1. Who are you really writing for?

If for the machine, do whatever you like.

If for other programmers -- give some consideration to what they will find understandable.

This includes your own future self!  An issue you may've noticed already, or maybe not if you're still fairly new to this, or just very consistent in your writing style.  (Which could kinda mean two things: that you're very consistent and familiar with your own dialect (or many dialects), or that you indeed format and comment things well already.  Preferably, the former is the latter. :) )

2. What is the purpose of this issue?

Globals are readable and writable by any module in the system, whether they "should" be able to or not.  Mind, that means semantically: C of course doesn't give a shit if you trample random memory, that's your own prerogative.  It's about visibility and scoping, and how much interface is exposed between modules.

Note that, depending on compiler version and declarations, globals may be automatically shared, or not.  In GCC < 8 I believe?, they were shared; after, not.  Scope can be controlled by prefixing static (local to module) or extern (shared).

The temptation is that, with globals shared and scoped, they become part of the interface, whether intended or not, and complexity grows massively.  Every outside reference to a variable, is one more reference you need to keep track of, with respect to state changes within the module (if indeed the variables declared within it are mostly/entirely used locally -- you don't have to, of course..!), the consistency thereof, and what ways the module can be interacted with.

Ultimately, what this drives towards is the matter of reusability, that a module should be largely self-contained, expose only its documented interfaces, and enforce that as such.

A recent example I used is this,
https://github.com/cwalter-at/freemodbus/tree/master/modbus
It's fairly old and mature, actively maintained (well, there are a couple PRs sitting around for a few years, but last I looked, all quite minor and easily implemented yourself), and very modular.  You implement the physical/interface bits in the port files, implement the callbacks (messages translated into read/write commands, you implement the read/writing yourself), pick the interface you want (on init), then poll in a main() loop.  The code is fairly compact, straightforward -- Modbus is a pretty thin and simple stack, but a stack it is -- and easy enough to understand.  So, I think it's a good illustration of how convenient this style of design and organization is.

Which leads into:

3. https://en.wikipedia.org/wiki/Dependency_injection

As mentioned above, it's another design pattern that can help simplify things.

The apparent downside for embedded purposes is, all this boilerplate doesn't matter, you're only ever going to use one configuration, and you're checking memory regularly (well, maybe) and it's all flat in the end, who cares.

Well, the overhead is small; in C, the function pointers used during MBinit() for example, will always emit a load, call (register indirect) operation (or, I think so, anyway?).  Distinctly slower than absolute call, let alone inlining the thing whole.  But how often are you calling MBinit()? Just once?  Yeah who cares about an extra five or 20 cycles.  And the polling is done, whatever, say every millisecond, what's another couple dozen cycles on that, who cares?

The worst part is probably interrupts, which are often written as callbacks in these sorts of things (see also: STM32 HAL and the like), so all registers on the ABI's clobber list must be saved and restored around the call.  But here still, it needn't be a problem.  For Modbus at least, conventional baud rates are slow (9600, 19200...) so few interrupts can fire per second.  YMMV for whatever kind of module, of course, but the point is, many things aren't performance sensitive, or nearly as much as you're apt to think in the embedded world.

In C++, more of these are likely to be optimized down, AFAIK, so, a constant function pointer at compile-time may end up inlined, say.  In that case, there's literally no downside.

Exposure to newer languages probably helps out as well.  Being familiar with say Java Objects (everything is an Object, no pointers, only references), or lambdas or other functional things (Factory design pattern; passing functions as parameters or objects; etc.), gives you a higher level perspective that you'd never realize deep down in the trenches of plain C.  Even if you're never using the full form of those structures, knowing that they're there, and that you could express what you're doing as a reduced form of one of these constructs -- can help organizing things.

Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 
The following users thanked this post: Jester

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11653
  • Country: my
  • reassessing directives...
Re: Global variables - Evil or not
« Reply #21 on: October 20, 2022, 11:26:14 pm »
there are enough materials in the net to educate about the why not to use them (on certain programming scale/topology/hierarchy/concept/design) this is more "theoretical" or "logical" rather than trivial matter such as to save memory space or make things faster to run etc, certainly not in the context of OP. if you happened to buy an academic books about teaching you into larger scale software/data design/structure, you will sometime see this hinted by the author who happened to be a professor or at the same level as people like Mr Bjarne. those who have been bitten know how to appreciate and know this is something for real albeit intangible with no physical appearance, those who have a hard time understanding the why, that means its none of their business, they can do whatever they like and certainly nothing will go wrong... i bet their software is simple enough to maintain no matter how complex they think it might be...

https://www.tutorialspoint.com/Why-should-we-avoid-using-global-variables-in-C-Cplusplus


Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 
The following users thanked this post: Jester

Offline mac.6

  • Regular Contributor
  • *
  • Posts: 225
  • Country: fr
Re: Global variables - Evil or not
« Reply #22 on: October 22, 2022, 08:13:19 am »
In embedded system, especially constrained ones, global variable are mostly required.
But what matters is how you use them.

Direct access to global variable is the culprit. this is the start of the spaghetti code, all your code is tied by the globals references.

So better use a global pointer/structure for one or more global context, then a bunch of accessor function.
This way you can easilly control access and reuse your code.

All the fuss about visibility/abstraction only matters if you share code or doing libraries. If you controll 100% of your code and partition it correctly it doesn't matter at all.
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8179
  • Country: fi
Re: Global variables - Evil or not
« Reply #23 on: October 22, 2022, 09:14:59 am »
Terminology:

NOT global, but file-scope static variable:

Code: [Select]
file.c:
static int var; // accessible to all functions in file.c

Actual global:
Code: [Select]
file.h:
extern int var; // include file.h to access var from any module

file.c:
int var;

You can also say var is now part of the interface of this module.


File-scope statics can't be realistically avoided in C, they store shared state between the module functions. Equivalent to private member variables in C++ class.

Actual globals can, and maybe should be avoided, but sometimes they are just the easiest way and they don't magically transform your code into shit. If you find yourself using globals all the time, you can ask yourself if you could abstract the functionality better so that, for example, uart.c does all UART-related things and interface only consists of a few functions, not variables.
« Last Edit: October 22, 2022, 09:17:05 am by Siwastaja »
 

Online ejeffrey

  • Super Contributor
  • ***
  • Posts: 3727
  • Country: us
Re: Global variables - Evil or not
« Reply #24 on: October 22, 2022, 05:51:34 pm »
There are a couple of problems with global variables, how big of a problem they are depend on your situation.

The first is name collisions and is really specific to C which has no good namespace support.  Almost any other language in common use has either default or optional module level namespaces.  This allows you to make a module variable visible globally but require it to be qualified by a module name when uses in other modules.  The standard way to avoid this in C is to use prefixes which works OK.  If you are going to use globals in anything reusable or more than a handful of .c files in a single directory I strongly recommend doing this.

The second is that you lose control over how a variable is used.  For instance if you want to make a project thread safe, you might need to add locks.  If you have accessors you have a way to do this that is much simpler than if you have to change every access.  Global variables can also have issues with order of initialization. If a global variable has complex initialization it can be difficult to ensure that it is initialized before access.  Dedicated accessor functions that check for and perform initialization can't completely solve this problem but at least give you a hook to solve it.

The above two problems are with the implementation of global variables.  The third problem is more with the concept of global state which is that global variables are basically by definition singletons.  There are a lot of instances where "global" state turns out to not be global.  GUI frameworks are notorious for this, treating the GUI handle and the event loop as global singletons.  This is undeniably convenient as you avoid passing context objects around in every part of your code.  It's particularly convenient in callback heavy code as it is one less but of context you have to figure out how to get back to your callback in a language with no native support for nested functions or closures.  But embedded applications are not immune to this, often treating things like "the" serial/console port as a global.  If a future implementation requires multiple IO devices can result in a lot of code that needs to be rewritten.

So not evil but something you should think about, and there are good reasons why some environments heavily restrict them.
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19522
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Global variables - Evil or not
« Reply #25 on: October 22, 2022, 06:59:49 pm »
Tools such as an IDE or even simply grep on the command line can help you find all the places a variable is used.

Thats complicated by the use of macros and pointers.

While the former need not be a problem in well written C, the latter is a pain in the backside. Not for nothing are there "believe me because I am omniscient" compiler directives to discount the possibility of aliasing.

Confession: I haven't used C professionally (except trivially) in a very long time. I can't even remember the outcome of the endless committee deliberations as to whether it should be possible or impossible for a cast to discard a const attribute (the "casting away constness" debate). There are good reasons for both options.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline paulca

  • Super Contributor
  • ***
  • Posts: 4055
  • Country: gb
Re: Global variables - Evil or not
« Reply #26 on: October 22, 2022, 08:15:37 pm »
As others have said it comes down to complexity, performance and footprint.

As your applications expand global variables may start to become difficult to work with.  By declaring them as global you are basically declaring them as "public free for all".  You will have been using them here, there and everywhere and keeping track of them in your head.  Have a few too many of them, or leave your project for a few weeks and come back and remembering how all those global variables interact might need you to re-read the whole code base again.  If that's 1000 lines, fine.  If it's 25 files and 10k lines, not so much.

Maybe not mentioned, but extremely important.  Team work.  When you have more than one person working on a project the tendency is to protect each other from mistakes by not having random global variables which could be miss understood or used by two different programmers in two different places that the other is not aware of.  That can lead to random bugs which will be a bear to find.

So your code gets big and your team has a few members.  You start writing wrappers around your data structures, putting some design patterns around them and your code size, memory size and performance all take a shift.

As this grows and grows it gets exponential.  At the top end, big enterprise code bases can be giga bytes in size with 100s of developers and lierally 99% of the code you write doesn't do anything, it's just structural framework and design patterns stacked on top of each other.  Somewhere buried under it all will be a few lines of code that actually have a tangible electronic effect beyond the CPU.  Like a socket.write.  99% of it is there to make the complexity manageable.

This is why people have been desperately trying to get big enterprise out of creating monolithic applications and move to micro-services and other component pipeline or bus architectures, then you can write small independent services which on their own are simple, self contained and  self protected "workers".  They will even exist in their own little projects that can be given to junior engineers without giving them a panic attack or taking 3 weeks to set up the IDE for the monolithic application code.

Obviously the hardware changes as you go up.  Once you get into the land of x86 or ARM CPUs and Giga bytes of RAM the data structures you use become much more dynamic, much, much heavier on CPU and Memory but a lot more useful and flexible.  No more managing delicate char buffers you will have "String" abstractions and Lists, Vectors, Maps, FIFOs, Queues etc. etc.  Want to take a full 60 seconds waiting on a Wifi connection?  That's fine, just make your UART buffer 10Mb.  It will still be there when you come back.

This is one of my personal procrastination points in MCU C...  avoiding dynamic allocation and trying to juggle all the strings you have to deal with.  It always seems either really, really clunky hacking through strings as arrays or really, really costly calling stdio and string.h functions.

Your man Johnathon Blow mentioned that when Twitter started it had like 2 engineers and released a dozen features a year.  Today it has nearly 2000 engineers and barely manages to release a single new feature a year!  That's what exponential complexity does to projects.
« Last Edit: October 22, 2022, 08:17:47 pm by paulca »
"What could possibly go wrong?"
Current Open Projects:  STM32F411RE+ESP32+TFT for home IoT (NoT) projects.  Child's advent xmas countdown toy.  Digital audio routing board.
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19522
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Global variables - Evil or not
« Reply #27 on: October 22, 2022, 08:31:09 pm »
...
This is why people have been desperately trying to get big enterprise out of creating monolithic applications and move to micro-services and other component pipeline or bus architectures, then you can write small independent services which on their own are simple, self contained and  self protected "workers".  They will even exist in their own little projects that can be given to junior engineers without giving them a panic attack or taking 3 weeks to set up the IDE for the monolithic application code.
...

It doesn't work out that way, of course. It is yet another cycle of the wheel. All that happens is that one form of complexity is removed, and replaced by another. And s/complexity/pain/, s/complexity/failure points/, etc

Having said that, the replacement system may be better (whatever that means). But usually that's merely because the whole lot has been dumped and replaced with something smaller that actually does what is required. Even that can be killed by an ignorant design authority stating the "new system must do what the old system does", i.e. implicitly including all the bugs that people have become used to living with.

To bring it back to the topic of global variables, just because a system is distributed doesn't mean there is nothing equivalent to a global variable in an embedded application. All that's happened is that the scale has changed.
« Last Edit: October 22, 2022, 08:46:47 pm by tggzzz »
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline langwadt

  • Super Contributor
  • ***
  • Posts: 4436
  • Country: dk
Re: Global variables - Evil or not
« Reply #28 on: October 22, 2022, 08:46:31 pm »
...
This is why people have been desperately trying to get big enterprise out of creating monolithic applications and move to micro-services and other component pipeline or bus architectures, then you can write small independent services which on their own are simple, self contained and  self protected "workers".  They will even exist in their own little projects that can be given to junior engineers without giving them a panic attack or taking 3 weeks to set up the IDE for the monolithic application code.
...

It doesn't work out that way, of course. It is yet another cycle of the wheel. All that happens is that one form of complexity is removed, and replaced by another. And s/complexity/pain/, s/complexity/failure points/, etc


as usually the attempted solution to too much bureaucracy is more bureaucracy ...
 
The following users thanked this post: MK14

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 3701
  • Country: gb
  • Doing electronics since the 1960s...
Re: Global variables - Evil or not
« Reply #29 on: October 22, 2022, 09:12:21 pm »
I use globals a lot, where useful.

But I always prefix them with g_ to make it obvious.

And declare them, and their initial value (if any), in main.c, not all over the place.

Globals, especially buffers, have many benefits compared to having them on the stack. One is deterministic (static) memory usage.
« Last Edit: October 22, 2022, 09:14:31 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 
The following users thanked this post: Ed.Kloonk

Offline uer166

  • Frequent Contributor
  • **
  • Posts: 893
  • Country: us
Re: Global variables - Evil or not
« Reply #30 on: October 23, 2022, 06:22:04 am »
Globals, especially buffers, have many benefits compared to having them on the stack. One is deterministic (static) memory usage.

You don't need a global to put something into static memory. A static keyword within a function limits scope to that function and also keeps it off the stack. I think the argument here is largely to do with scope, not where the variable goes.
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 3701
  • Country: gb
  • Doing electronics since the 1960s...
Re: Global variables - Evil or not
« Reply #31 on: October 23, 2022, 07:02:42 am »
True, declare "static" within a function. Although you then cannot find the address of it in the .map file; this may be development kit dependent. One can find the address by setting a breakpoint and seeing what it is.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11653
  • Country: my
  • reassessing directives...
Re: Global variables - Evil or not
« Reply #32 on: October 23, 2022, 10:20:11 am »
True, declare "static" within a function. Although you then cannot find the address of it in the .map file
and why do you care about where a variable is located?
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 3701
  • Country: gb
  • Doing electronics since the 1960s...
Re: Global variables - Evil or not
« Reply #33 on: October 23, 2022, 10:55:34 am »
For debugging, to check whether it is 32 bit aligned, etc. Also not all memory regions are equally accessible e.g. on the STM 32F4, DMA cannot access CCM memory.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6266
  • Country: fi
    • My home page and email address
Re: Global variables - Evil or not
« Reply #34 on: October 23, 2022, 11:15:33 am »
If you just want to know the address, you can always declare a variable in a suitable ELF section recording the address.  For example,
Code: [Select]
static uint32_t  myvar;

const uintptr_t  address_of_myvar __attribute__((section ("addresses"))) = (uintptr_t)(&myvar);
In your linker script, you can just drop the entire section, when not debugging.  Otherwise, put it in Flash/ROM.
 
The following users thanked this post: MK14

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11653
  • Country: my
  • reassessing directives...
Re: Global variables - Evil or not
« Reply #35 on: October 23, 2022, 02:26:55 pm »
if i want to check alignment or endianess i will just cast it (usually array) into some other datatype/union and watch its value, this applies even to dynamic allocated memory.
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3147
  • Country: ca
Re: Global variables - Evil or not
« Reply #36 on: October 23, 2022, 06:12:37 pm »
The moment you google "global variable" half the comments are DON'T DO IT you will burn in hell.

Internet is an echo-chamber. People repeat and re-post what they see. Many of them work hard trying to put their pages on the top of Google searches. If something is everywhere, it does not necessarily have any merit.

If you think the gloabal varibles are bad try to asses that

- you can clearly explain to yourself why global variables are bad
- you are able to write a program where global variables cause the problem
- the problem is likely to occur in the particular program you're about to write
- the danger of this problem actually occurring outweighs the benefits of using global variables

If you affirmatively say "yes" to all of the four then you shouldn't use global variables

I wouldn't waste much time trying to follow different tips from the Internet, use your own judgment instead ... but wear tinfoil at all times.
 
The following users thanked this post: neil555

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
Re: Global variables - Evil or not
« Reply #37 on: October 23, 2022, 08:52:03 pm »
Although you then cannot find the address of it in the .map file; this may be development kit dependent.
Mmmhh...
From:
Code: [Select]
static const char *put_threads(bool first)
{
    static TCB task_id;
    ...
My ld.lld (clang linker) produced map file contains:
Code: [Select]
20009c4c 20009c4c        4     4         CMakeFiles/SDR1062.dir/source/gdbdebug/FreeRTOSdbg.c.obj:(.bss.put_threads.task_id)
20009c4c 20009c4c        4     1                 put_threads.task_id

I'm using --ffunction-sections, so task_id above is in the bss section of put_threads.

With gcc/ld, I also see them (this is an old map, I can't try right now to generate a new one):
Code: [Select]
.bss.y.10453   0x20000ba0       0x80 ./source/main.oFrom:
Code: [Select]
void TestTask(void *p)
{
    ...
    for (;;)
    {
        ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
        GPIO_PortSet(LED_B_GPIO, LED_B_PORT, LED_B_PIN_MASK);
        static uint8_t y[128];
        ...

Here, the 10453 is added to make sure there are no conflicts with external linkage variables.


For debugging, to check whether it is 32 bit aligned, etc. Also not all memory regions are equally accessible e.g. on the STM 32F4, DMA cannot access CCM memory.
If the natural alignment is less than 32 bits, one of course cannot rely on it - any change in the code might affect it.
The compiler takes care of that for you, if something special is needed you can instruct it (e.g. with _Alignas() in C11 and later).
As for the various types of memory, the variable declaration itself plus the linker script should be enough to understand where it ends up (or the map file!)
Nandemo wa shiranai wa yo, shitteru koto dake.
 
The following users thanked this post: snarkysparky

Offline paulca

  • Super Contributor
  • ***
  • Posts: 4055
  • Country: gb
Re: Global variables - Evil or not
« Reply #38 on: October 24, 2022, 11:11:52 am »
Interesting points on the topic of hiding the fact variables are global.  This generates a LOT of discussion and arguments in Enterprise space.  For example, a standard technique in Java is just to have "public static" members of a class.  As long as the class loader you are referencing has that class you can access that variable anywhere.  OOP Priests will complain and whine and waste effort creating non-public singleton configuration frameworks (which, still at the end of the day accomplish the same thing)  and in 6 months everyone will have started writing public static members again to avoid it!  Having been the culprut of this at least a dozen times, my response was always, "I needed it done today.  You are free to raise a tech debt Jira for it.  Let's move on."

Another approach is using some form of dependency injection such that all the classes keep all their stuff private and you let the framework inject them where they are needed.

It's a paper cannon.  You just inject the dependency into your code and effectively, it IS global.  It's just the framework giving you the reference where ever you want it instead of you making it public yourself.  It's the same thing just spelt different and the only meer improvement is that technically, you have a little more control.  If you can stop other developers giving themselves control.  It becomes a race between people giving themselves access to things and people trying to secure the code against the same engineers who are writing it.  It wastes so much time, effort and money and barely achieves anything beyond making it all a little more complicated and costly.

If you follow on down this route through Java you will start to encounter frameworks which practically write a whole new language on top of Java with almost every single member variable existing as an "implements Optional, Immutable" and insisting on making all state read-only and forcing you to use specific syntax and proceedures to modify state.  Note that this WILL require a LOT of copy by value mechanics as actual (pointer) references are not sufficiently protected in Java.  (Pedants:  I mean literally return obj.cloneAsImmutable() type stuff.)

I think it matters what you are doing in the code.  Can a mistake (by machine or man) by undone easily?  Is there a threat to life involved?  I can see how a system modifying a critical value in a plane's air data computer must go through checks and balances and there has to be proceedures, such as multi-sensor elections, value averaging, limits, exceptions and so on and so forth.  (relevant case of Toyota's ECU code causing some accidents, poor buggers had code analysists publish their static code analysis and tech debt lists in court).

EDIT:  I think the aim of protecting the code can either be it's criticality as above or maybe it's security.  Usually it's not the intent to protect against mallace within the engineering team, but rather to protect against accidentally modifying something in a way you shouldn't.  Protecting against accident, ignorance and possibly negligence. (or incompetence)

The trouble is... people get interested in that stuff, start to learn it and in order to continue to learn it and prove it was worth learning they try and enforce it everywhere.

Writing C for MCUs is a breath of fresh air when you see things like blind, bare, global functions and call backs already declared.  Coming from enterprise world, this ironically almost seems like black magic voodoo, exactly as an MCU engineer would see something like JNDI dependency injection.

EDIT:  I noted that STM are currently under going a battle of similar lines in their HAL libraries.  Lots of IFDEFs popping up removing the "legacy weak global callbacks" and making you registerCallbacks (inversion of control pattern).   Welcome to my world :)
« Last Edit: October 24, 2022, 11:32:04 am by paulca »
"What could possibly go wrong?"
Current Open Projects:  STM32F411RE+ESP32+TFT for home IoT (NoT) projects.  Child's advent xmas countdown toy.  Digital audio routing board.
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11653
  • Country: my
  • reassessing directives...
Re: Global variables - Evil or not
« Reply #39 on: October 24, 2022, 11:28:41 am »
It's a paper cannon.  You just inject the dependency into your code and effectively, it IS global.  It's just the framework giving you the reference where ever you want it instead of you making it public yourself.  It's the same thing just spelt different and the only meer improvement is that technically, you have a little more control.  If you can stop other developers giving themselves control.  It becomes a race between people giving themselves access to things and people trying to secure the code against the same engineers who are writing it.  It wastes so much time, effort and money and barely achieves anything beyond making it all a little more complicated and costly.
it is to control codes/modules/classes coupling, to ease debugging and maintainability. those concept are created by computing scientist, not a programmer somewhere at the backyard. yes it introduced bloatness and complexity into coding, but that to maintain some consistent protocol/channel on how to access things. we can argue about waste of processing power, but its not the problem to computer scientists, its the problem for engineers, processing power will keep growing, but the theory will remains and will be more and more relevant in time. this also we can assume it for near unlimited resources and processing power, ie on larger scale of software and hardware. as stated repeatedly, if your system is small and limited, its not for you. dont try to use a hydraulic jack to push a nail into the wood, thats certainly nonsensical.
« Last Edit: October 24, 2022, 11:30:29 am by Mechatrommer »
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline Warhawk

  • Frequent Contributor
  • **
  • Posts: 821
  • Country: 00
    • Personal resume
Re: Global variables - Evil or not
« Reply #40 on: October 25, 2022, 09:45:36 am »
I occasionally use global variables too. I don't think this is evil if you understand problems that globals may cause. From my experience, the worst codes to debug, maintain and understand, came from coders/programmers who were trying to do "everything right".
I personally rather see a small, short, crisp and easy to understand code using global variables than a complex strict encapsulation on a small microcontroller.
However, I am only a hobby coder and this is my opinion.
   

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3147
  • Country: ca
Re: Global variables - Evil or not
« Reply #41 on: October 25, 2022, 01:38:22 pm »
... yes it introduced ... complexity into coding

The complexity is the problem. A simpler program uses less resources, is less prone to bugs, is easier to write, to understand, and to maintain.

One of old programmers said: "novices ignore complexity, professionals deal with complexity, geniuses remove complexity". I don't even know what to say about those who deliberately add complexity.
 

Offline Warhawk

  • Frequent Contributor
  • **
  • Posts: 821
  • Country: 00
    • Personal resume
Re: Global variables - Evil or not
« Reply #42 on: October 25, 2022, 07:38:14 pm »

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11653
  • Country: my
  • reassessing directives...
Re: Global variables - Evil or not
« Reply #43 on: October 25, 2022, 08:32:37 pm »
Also one to the topic http://www.ganssle.com/articles/globals.htm
that article starts with strawman fallacy...
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline uer166

  • Frequent Contributor
  • **
  • Posts: 893
  • Country: us
Re: Global variables - Evil or not
« Reply #44 on: October 25, 2022, 11:42:50 pm »
Also one to the topic http://www.ganssle.com/articles/globals.htm
that article starts with strawman fallacy...

Seriously.. what the hell are they smoking:

Quote
Globals break the important principle of information hiding. Anyone can completely comprehend a small system with ten variables and a couple of hundred lines of code. Scale that by an order of magnitude or three and one soon gets swamped in managing implementation details. Is user_input a char or an int? It's defined in some header, somewhere. When thousands of variables are always in scope, it doesn't take much of a brain glitch or typo to enter set_data instead of data_set, which may refer to an entirely unrelated variable.

The same exact thing can be set by "OOP" trash with a thousands of getters and setters, the problem has nothing to do with globals per se.
 

Offline Warhawk

  • Frequent Contributor
  • **
  • Posts: 821
  • Country: 00
    • Personal resume
Re: Global variables - Evil or not
« Reply #45 on: October 26, 2022, 07:45:50 am »
You're never happy. This forum became one insult after another. I go for a walk.

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19522
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Global variables - Evil or not
« Reply #46 on: October 26, 2022, 07:54:16 am »
You're never happy. This forum became one insult after another. I go for a walk.

I don't see any insults in the preceding two messages.

I do see something irrelevant and some poor reasoning. Such is life.

Walks are good for clearing the brain :)
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: Global variables - Evil or not
« Reply #47 on: October 26, 2022, 08:06:12 am »
Also one to the topic http://www.ganssle.com/articles/globals.htm
that article starts with strawman fallacy...

Seriously.. what the hell are they smoking:

Quote
Globals break the important principle of information hiding. Anyone can completely comprehend a small system with ten variables and a couple of hundred lines of code. Scale that by an order of magnitude or three and one soon gets swamped in managing implementation details. Is user_input a char or an int? It's defined in some header, somewhere. When thousands of variables are always in scope, it doesn't take much of a brain glitch or typo to enter set_data instead of data_set, which may refer to an entirely unrelated variable.

The same exact thing can be set by "OOP" trash with a thousands of getters and setters, the problem has nothing to do with globals per se.

You (should) know who the author is and how to weight his opinion.
I stand with Warhawk, too many pissing contests lately
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
Re: Global variables - Evil or not
« Reply #48 on: October 26, 2022, 09:11:20 am »
Gannsle's article goes a bit for hyperbole, and for some counterfactual information (Ariane 5 was, in fact, lost because ranges were checked!).
But I have seen and fought with legacy, globals galore, code. It's not fun or productive.
Still, he makes good points on how to write robust code: limit the globals, write self-contained modules with clear interfaces, yadda yadda.
Nothing really revolutionary, in my view.

Just a sample: in one of my projects, about 200 kLOC, I have a half dozen of globals:
  • They provide state to whole program.
  • They can be read everywhere.
  • They are written in exactly two points: user input, or loading of a saved preset.
Given the above, I did not bother with accessors. Should the need arise of more writers, I might consider it.
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4040
  • Country: nz
Re: Global variables - Evil or not
« Reply #49 on: October 26, 2022, 09:32:12 am »
Gannsle's article goes a bit for hyperbole, and for some counterfactual information (Ariane 5 was, in fact, lost because ranges were checked!).

Never check for any error condition that you don't know how to handle better than just ignoring it!

Writing if (unexpected) trigger_self_destruct() is often not an improvement.
 
The following users thanked this post: newbrain

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: Global variables - Evil or not
« Reply #50 on: October 26, 2022, 10:09:15 am »
Still, he makes good points on how to write robust code: limit the globals, write self-contained modules with clear interfaces, yadda yadda.
Nothing really revolutionary, in my view.
True, nothing groundbreaking but it's worth being repeated to death. The importance of writing clear, understandable, clean code is lost on the majority of programmers. Limiting globals to enforce tidiness and discourage laziness is ultimately good.

Quote
Just a sample: in one of my projects, about 200 kLOC, I have a half dozen of globals:
  • They provide state to whole program.
  • They can be read everywhere.
  • They are written in exactly two points: user input, or loading of a saved preset.
same situation.

Quote
Given the above, I did not bother with accessors. Should the need arise of more writers, I might consider it.

bingo. Problem is when more than one person is touching the code.
 
The following users thanked this post: newbrain

Offline paulca

  • Super Contributor
  • ***
  • Posts: 4055
  • Country: gb
Re: Global variables - Evil or not
« Reply #51 on: October 26, 2022, 10:11:07 am »
Gannsle's article goes a bit for hyperbole, and for some counterfactual information (Ariane 5 was, in fact, lost because ranges were checked!).

Never check for any error condition that you don't know how to handle better than just ignoring it!

Writing if (unexpected) trigger_self_destruct() is often not an improvement.

There is worse than that. 

A-holes who put hard runtime asserts into their library code.
"What could possibly go wrong?"
Current Open Projects:  STM32F411RE+ESP32+TFT for home IoT (NoT) projects.  Child's advent xmas countdown toy.  Digital audio routing board.
 

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21698
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: Global variables - Evil or not
« Reply #52 on: October 26, 2022, 10:34:22 am »
Somewhat tangential, but something to keep in mind whenever you see clouds of holy wars gathering...



tl;dr viral "problems" go viral, in part, specifically because, the experts that know those problems are shite, and avoid them.  Which voluntarily excludes them from the conversation.  Then there's no authoritative voice to guide conversation, and it ends up dividing into camps that are mutually "obviously right" in their answers.  Which, while they might be "right" more or less, the truer answer is, "it's a stupid question" -- it should be reframed to one that makes sense.  But then the answer will be obvious and uninteresting to talk about....

Put another way: an aspect of critical thought is not just to 1. recognize experts on the topic, but 2. recognize their absence when it happens -- that is, even on topics that they are likely to have seen, and still have not participated in.  Consider if there might be a reason for that.  It could just be accidental of course, but it might be intentional.

So, keep that in mind with respect to "controversial" topics like this.  Fortunately, this thread, I think, has drawn a fair diversity of users here, but that might not be the case everywhere, especially where the quality of discourse (in the thread, or more broadly) has been poor, further shooing off experts.

More directly: this topic, as most basically stated in the title, easily leads to divisive thinking.  It is an issue with some nuance, but one must look deeper to appreciate those nuances, and the question can be phrased better (though in this case it may take knowledge of the situation and possible alternatives to know how better to phrase it; that happens sometimes...often?..).

Which is kind of a side issue these days; ironically, despite the diversity and scale of the internet, it's increasingly hard to find resources on questions like this, other than on Stack for example, and as it's not a conversation platform, there may be less incentive for experts to contribute to mostly-correctly answered questions.  Or they assume (erroneously) that a reader may be able to find / anticipate related issues that haven't been mentioned yet.  Or that answers change over time (especially for software, as languages, apps and OSs get upgraded) but nothing brings topics to the front for further review until commented upon

Not that the SNR is any better at places like here.  For question-answers, I'd rather skip to the answers rather than sift through ten pages of fluff (or a hundred..).  But on those topics where conversation is necessary, yeah.

Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11653
  • Country: my
  • reassessing directives...
Re: Global variables - Evil or not
« Reply #53 on: October 26, 2022, 11:20:48 am »
Which, while they might be "right" more or less, the truer answer is, "it's a stupid question" it should be reframed to one that makes sense.  But then the answer will be obvious and uninteresting to talk about....
ditto! when i see this kind of riddle i will just skip it. when other FB newcomers will like to answer to show how clever high IQ they are. 9 = 90 is just plain stupid written by moron, period. it will be more acceptable if 9 --> 90 (read mapped). is like in the other thread discussing about a scope, someone came and said DS1054Z is a "sampling oscilloscope", it came down to terminology differences. but i dont think its relevant to this thread. this topic is about "why should i care about something that is none of my business?", my context is this, but the problem is not in my context, but i would like to ask anyway. so 2 schools came, imho both are right within their own context. because once upon a time we came from school #1 so we understand why they say its not a problem.
« Last Edit: October 26, 2022, 11:25:22 am by Mechatrommer »
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6266
  • Country: fi
    • My home page and email address
Re: Global variables - Evil or not
« Reply #54 on: October 26, 2022, 12:17:50 pm »
the truer answer is, "it's a stupid question" -- it should be reframed to one that makes sense.
I prefer the term "wrong question", but only because there are lots of people who are afraid of asking questions because they fear being ridiculed or pointed out as stupid.

Reason being, it is not stupid, per se, just wrong.  Many times those asking the wrong question have to be explained how the question is wrong.  Typical reasons in my experience are loaded questions (that cannot be answered) and incorrect premises or assumptions leading to the incorrect question being posed, and especially that in the logic chain of the current overall problem a previous question before this was answered incorrectly, making this entire question irrelevant and useless.

Stupid is when after having been pointed that out, the person just repeats the same question.  Then ridicule is appropriate; but not as the initial reaction.

In physics, various terms are used from "nonsensical" (as in "irrational", "meaningless" or "without practical meaning") to "ill-posed" (extending the well-posed problem concept by Hadamard), because mathematics is only applied to describe the behaviour of systems, and if the initial problem/question is posed wrong, then the results can be horribly wrong.  In particular, in most physics simulations, the very first thing a physicist does when they obtain a set of results, is to check if it makes any sense.

I wish English had a term with suitable connotations here, like "missensical" or "mis-asked", which would immediately tell the asker that one or more of the premises or axioms related to the question are incorrect/unsuitable/unphysical, making the question itself irrelevant, necessitating a step back in the chain of logic for the underlying problem at hand –– but without making the asker feel stupid.  We all make mistakes, and everyone should always have a go at fixing their question at least once.  Missing important details is a very easy error to make.  Perhaps "erroneous question"?  Or is that too pretentious?  :-//
 
The following users thanked this post: MK14

Offline RoGeorge

  • Super Contributor
  • ***
  • Posts: 6207
  • Country: ro
Re: Global variables - Evil or not
« Reply #55 on: October 26, 2022, 12:19:25 pm »
Interesting points on the topic of hiding the fact variables are global.  This generates a LOT of discussion and arguments in Enterprise space.


Doh, but I bet it does, especially on Enterprise!



 ;D

Offline langwadt

  • Super Contributor
  • ***
  • Posts: 4436
  • Country: dk
Re: Global variables - Evil or not
« Reply #56 on: October 26, 2022, 01:18:14 pm »
Gannsle's article goes a bit for hyperbole, and for some counterfactual information (Ariane 5 was, in fact, lost because ranges were checked!).

Never check for any error condition that you don't know how to handle better than just ignoring it!

Writing if (unexpected) trigger_self_destruct() is often not an improvement.

https://en.wikipedia.org/wiki/Battleshort :)
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11653
  • Country: my
  • reassessing directives...
Re: Global variables - Evil or not
« Reply #57 on: October 26, 2022, 02:04:32 pm »
the truer answer is, "it's a stupid question" -- it should be reframed to one that makes sense.
I prefer the term "wrong question", but only because there are lots of people who are afraid of asking questions because they fear being ridiculed or pointed out as stupid.
there are stupid content creators only for hunting "likes/views", and there are stupid followers, who react to the first's video... the video creator above is the later. they dont ask question, they try to establish their point of view through wrong notations, leading to misconception and harm esp to kids just started going to school.

Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 
The following users thanked this post: pcprogrammer

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 3712
  • Country: nl
Re: Global variables - Evil or not
« Reply #58 on: October 26, 2022, 02:09:14 pm »


Nothing wrong with that. Just fill in the missing bits in your mind. The answer is 12. :-DD

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 3712
  • Country: nl
Re: Global variables - Evil or not
« Reply #59 on: October 26, 2022, 02:19:43 pm »

Online MK14

  • Super Contributor
  • ***
  • Posts: 4540
  • Country: gb
Re: Global variables - Evil or not
« Reply #60 on: October 26, 2022, 02:26:57 pm »
I wish English had a term with suitable connotations here, like "missensical" or "mis-asked", which would immediately tell the asker that one or more of the premises or axioms related to the question are incorrect/unsuitable/unphysical, making the question itself irrelevant, necessitating a step back in the chain of logic for the underlying problem at hand –– but without making the asker feel stupid.

I'd suggest, a suitable English term might be ...
Ambiguous or Ambiguous question.

E.g. What is 1 + ! = ?
The answer could be 2, because I typed '!' instead of '1', or it could be an entirely different question.  Hence it is AMBIGUOUS, because you can't tell readily/easily from the question, what the right answer is (without extra information, knowledge or help, from the question source).

I.e. The question is (possibly) malformed (e.g. a typing mistake, or issue with the fonts, so it was suppose to be a '1', but came out as a '!', somehow).
 
The following users thanked this post: PlainName, pcprogrammer

Offline timenutgoblin

  • Regular Contributor
  • *
  • Posts: 190
  • Country: au
Re: Global variables - Evil or not
« Reply #61 on: October 26, 2022, 02:32:02 pm »
Then there's no authoritative voice to guide conversation, and it ends up dividing into camps that are mutually "obviously right" in their answers.  Which, while they might be "right" more or less, the truer answer is, "it's a stupid question" -- it should be reframed to one that makes sense.  But then the answer will be obvious and uninteresting to talk about....


Which, while they might be "right" more or less, the truer answer is, "it's a stupid question" it should be reframed to one that makes sense.  But then the answer will be obvious and uninteresting to talk about....
ditto! when i see this kind of riddle i will just skip it. when other FB newcomers will like to answer to show how clever high IQ they are. 9 = 90 is just plain stupid written by moron, period. it will be more acceptable if 9 --> 90 (read mapped).


Nothing wrong with that. Just fill in the missing bits in your mind. The answer is 12. :-DD
 
The following users thanked this post: pcprogrammer

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 3712
  • Country: nl
Re: Global variables - Evil or not
« Reply #62 on: October 26, 2022, 02:32:46 pm »
E.g. What is 1 + ! = ?

And then the answer would be 11  |O  :-DD (See the video Mechatrommer posted)

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6266
  • Country: fi
    • My home page and email address
Re: Global variables - Evil or not
« Reply #63 on: October 26, 2022, 04:12:55 pm »
the truer answer is, "it's a stupid question" -- it should be reframed to one that makes sense.
I prefer the term "wrong question", but only because there are lots of people who are afraid of asking questions because they fear being ridiculed or pointed out as stupid.
there are stupid content creators only for hunting "likes/views", and there are stupid followers, who react to the first's video... the video creator above is the later. they dont ask question, they try to establish their point of view through wrong notations, leading to misconception and harm esp to kids just started going to school.
I consider those more like "lies and fallacies masquerading as questions", myself.

I don't like even those called "stupid questions", because as I said, it makes those who just don't know the difference yet afraid of asking questions –– and that means they never learn to ask good questions.  And the world becomes less, if we do not ask good questions.

I'd suggest, a suitable English term might be ...
Ambiguous or Ambiguous question.
Hmm... ambiguous: open to multiple interpretations.  That's not it, because the point is that the question itself is incorrect, not that it can be interpreted incorrectly.  In face-to-face, I can often infer the correct interpretation of ambiguous questions –– like "When you were carrying that TV yesterday, did you notice the friendly squirrel at front?  Did you bring it inside okay?" typically "it" referring to the TV, and not to the squirrel.  In written text, it is similarly common for the exact interpretation to be inferrable from the surrounding context, often subsequent text, leaving the interpretation in a Schrödinger state for a paragraph or two.

To be clear, I'm referring to questions like "Why isn't there any solutions to x*x - 2.0 = 0?", when the asker is really asking why their C code using the float type (float x = sqrtf(2.0f); float y = x*x - 2; if (y == 0) printf("Okay!\n"); else printf("Fail!\n");) fails.  I indeed do occasionally answer this kind of questions, often with a snarky initial bite to get the OP out of the passive funk (indicated by the, uh, "inane" question they posed?), followed with actual useful help.

And also questions like "I want to fix this engine using these two q-tips and a crow feather", or their programming or engineering or electronics equivalent.  These are super-constrained so that no realistic solution is possible, unless you start by "First, trade one of the q-tips for at least two rubber strings no less than four inches in diameter", and describe the next thousand or so steps in detail.

(And yes, I kinda like "inane question" even better than "wrong question", because its dictionary definition fits like a finger in a nostril.  It's just that I don't see it used in everyday speech, so I think it might be perceived a bit snotty.)
 
The following users thanked this post: MK14

Online MK14

  • Super Contributor
  • ***
  • Posts: 4540
  • Country: gb
Re: Global variables - Evil or not
« Reply #64 on: October 26, 2022, 04:51:37 pm »
E.g. What is 1 + ! = ?

And then the answer would be 11  |O  :-DD (See the video Mechatrommer posted)

One solution (to that video you mentioned), would be to say to the, possibly problematic pupil, towards the beginning of the video.  You have won a big prize, with 22 nice sweets in it.  The only catch, is you have to give just 2 sweets, to another pupil, and another two sweets, to a different pupil.
How many sweets, do I remove from the prize bag, for the other pupils?
4 or 22 sweets?
« Last Edit: October 26, 2022, 04:53:11 pm by MK14 »
 
The following users thanked this post: pcprogrammer

Online MK14

  • Super Contributor
  • ***
  • Posts: 4540
  • Country: gb
Re: Global variables - Evil or not
« Reply #65 on: October 26, 2022, 05:11:44 pm »
I'd suggest, a suitable English term might be ...
Ambiguous or Ambiguous question.
Hmm... ambiguous: open to multiple interpretations.  That's not it, because the point is that the question itself is incorrect, not that it can be interpreted incorrectly.  In face-to-face, I can often infer the correct interpretation of ambiguous questions –– like "When you were carrying that TV yesterday, did you notice the friendly squirrel at front?  Did you bring it inside okay?" typically "it" referring to the TV, and not to the squirrel.  In written text, it is similarly common for the exact interpretation to be inferrable from the surrounding context, often subsequent text, leaving the interpretation in a Schrödinger state for a paragraph or two.

To be clear, I'm referring to questions like "Why isn't there any solutions to x*x - 2.0 = 0?", when the asker is really asking why their C code using the float type (float x = sqrtf(2.0f); float y = x*x - 2; if (y == 0) printf("Okay!\n"); else printf("Fail!\n");) fails.  I indeed do occasionally answer this kind of questions, often with a snarky initial bite to get the OP out of the passive funk (indicated by the, uh, "inane" question they posed?), followed with actual useful help.

And also questions like "I want to fix this engine using these two q-tips and a crow feather", or their programming or engineering or electronics equivalent.  These are super-constrained so that no realistic solution is possible, unless you start by "First, trade one of the q-tips for at least two rubber strings no less than four inches in diameter", and describe the next thousand or so steps in detail.

(And yes, I kinda like "inane question" even better than "wrong question", because its dictionary definition fits like a finger in a nostril.  It's just that I don't see it used in everyday speech, so I think it might be perceived a bit snotty.)

But you don't know if the question is incorrect or not (with absolute 100% certainty), that in itself, maybe a considerably harder question/problem to solve.  Hence the term ambiguous.

An expert on C, on this forum, may take one look at it, and say something like, "Since version xyz.123...... of the C standard, that (hypothetical, no connection to the C code you just mentioned) expression is always defined as ...".

Or later in the job interview, they might say, that the question was purposely created to have no definitive exact answers.  In order to make sure the possible future employee, is confident enough to simply say "They don't know the answer", or the question is ambiguous or badly formed (incorrect question).

It might be that (the reader of the question), missed some additional information/clues.  Which made the question answerable.  E.g. A schematic, which says all resistors are 1%, 0.25watt metal film, unless stated otherwise.

In other words, MAYBE the question is faulty, but it could also be that the reader (of the question), is simply mistaken or lacking experience, which would make the question unambiguous to them.  So simply saying the question is incorrect, is NOT that simple.

So I still think the term, ambiguous, is probably best.

Real Life Example (from memory, so might be wrong, also I can't 100% remember the original question, so I may have changed it a fair bit).
There was an online electronics test quiz, with (at the time it was written), perfectly valid questions.  But it said something like:
"How many transistors, might there be on a high complexity integrated circuit?".
A:..10,000
B:..1 million
C:..None of these answers
 
Nowadays, the correct answer is probably C, but at the time the question was created, answer B, or even A, could be correct.  So I actually gave the wrong (as regards current technology) answer, in the hope it was the correct answer for when the online quiz question was created.

EDIT: On reflection, you could always say "Incorrect Question", I can't really object.
« Last Edit: October 26, 2022, 05:45:54 pm by MK14 »
 

Offline AVI-crak

  • Regular Contributor
  • *
  • Posts: 125
  • Country: ru
    • Rtos
Re: Global variables - Evil or not
« Reply #66 on: October 26, 2022, 11:42:36 pm »
I have used global variables forever and have never had any issues. Am I missing something?
Hint, a global variable should be declared like this:
Code: [Select]
register volatile uint32_t  __very_important_5214     asm     ("r7");
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4040
  • Country: nz
Re: Global variables - Evil or not
« Reply #67 on: October 27, 2022, 12:01:06 am »
I have used global variables forever and have never had any issues. Am I missing something?
Hint, a global variable should be declared like this:
Code: [Select]
register volatile uint32_t  __very_important_5214     asm     ("r7");

I've done that a few times, but I think I used r9.

Works very nicely, even calling out to libraries that don't see this declaration (e.g. 3rd party) -- as long as you don't have any callback functions passed to them (including virtual functions in your own derived classes).
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14490
  • Country: fr
Re: Global variables - Evil or not
« Reply #68 on: October 27, 2022, 01:19:35 am »
It compiles, so it works.TM ;D
 
The following users thanked this post: paulca

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6266
  • Country: fi
    • My home page and email address
Re: Global variables - Evil or not
« Reply #69 on: October 27, 2022, 08:04:12 am »
It compiles, so it works.TM ;D
You monster! :rant:
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19522
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Global variables - Evil or not
« Reply #70 on: October 27, 2022, 09:01:56 am »
It compiles, so it works.TM ;D

The modern variant of that is "it passes the unit tests, so it works".

Regrettably I couldn't trademark that because it is common usage :(
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline langwadt

  • Super Contributor
  • ***
  • Posts: 4436
  • Country: dk
Re: Global variables - Evil or not
« Reply #71 on: October 27, 2022, 09:20:19 am »
It compiles, so it works.TM ;D

The modern variant of that is "it passes the unit tests, so it works".

Regrettably I couldn't trademark that because it is common usage :(

so it works so it ships
 

Offline paulca

  • Super Contributor
  • ***
  • Posts: 4055
  • Country: gb
Re: Global variables - Evil or not
« Reply #72 on: October 27, 2022, 09:56:54 am »
It compiles, so it works.TM ;D

The number of times in work you will here me say, "Just run it!  Stop checking it, run it and you'll find out if it works."  LOL
"What could possibly go wrong?"
Current Open Projects:  STM32F411RE+ESP32+TFT for home IoT (NoT) projects.  Child's advent xmas countdown toy.  Digital audio routing board.
 

Offline paulca

  • Super Contributor
  • ***
  • Posts: 4055
  • Country: gb
Re: Global variables - Evil or not
« Reply #73 on: October 27, 2022, 10:01:04 am »
On the debate.  I find this forum awesome because there are so many, very, very smart people in here.  From a wide range of backgrounds and views.

The original topic was just the cat thrown to the pigeons.

It went how I would have expected it to... if the OP wanted an actual answer, then I don't think this would be the place to ask.  I for one wasn't taking it seriously, just a water cooler heated debate we will all just walk away from back to our benchs and desks and mummble about for a while.

My own opinions in this were delibrately biased against complexity, however I'll be the first to introduce standards, conventions and best practices in a project in work.  IF they are necessary.

The only negative that drags it down is when the attacks turn from the ideas to the people who proposed them.  If you find yourself using "you" in the none 2nd sense and are indeed directing "you" to an individual and not the idea.  I would suggest you stop and consider it rude.  Ideas are stupid, it doesn't mean the person with that idea is stupid.  Consider the gold fish thought experiments.
« Last Edit: October 27, 2022, 10:08:34 am by paulca »
"What could possibly go wrong?"
Current Open Projects:  STM32F411RE+ESP32+TFT for home IoT (NoT) projects.  Child's advent xmas countdown toy.  Digital audio routing board.
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11653
  • Country: my
  • reassessing directives...
Re: Global variables - Evil or not
« Reply #74 on: October 27, 2022, 10:53:35 am »
The number of times in work you will here me say, "Just run it!  Stop checking it, run it and you'll find out if it works."  LOL
almost everytime immediately you will know it works... what you are going to find out sooner or later is if it doesnt work... and worse when you already send the project to the moon. so i guess more precise word is... "run it and you'll find out if it doesnt work"... hint: semantic error... ::)
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6266
  • Country: fi
    • My home page and email address
Re: Global variables - Evil or not
« Reply #75 on: October 27, 2022, 10:58:29 am »
One useful approach to use and avoidance of global variables is to consider applications and the conflict between single or multiple documents per process.

It is useful to group the state variables in an application between "application state" (application configuration, like which windows are shown and where, what language is the user interface, and so on) and "document state" (document or current task configuration, like say page size, content language, and so on).

If you write an application that creates a new process for each document opened, then you can keep document state in global variables just like application state.  However, each instance is separate, so if you e.g. change the user interface language in one, other open instances are not affected.
(Note that you do not actually waste memory doing this in current operating systems, because they use virtual memory, and directly map libraries and executables to memory.  Each process has their own stack and kernel metadata, and of course any read-write data memory segments/sections/areas, but there is only one copy of the read-only code segments in memory.)

If you write an application that can handle multiple documents at once, you have "application state" (configuration) and "document state" (document settings).  While "application state" is global to the entire process, the "document state" is specific to each document, and you must not keep any document state in global variables.  If the user starts a new copy of the application while one is running, instead of running normally, the new instance just sends an event or file open request or new document request to the already running application, and then exits.



Now, extend that idea to a library, or even to a facility in your own program or microcontroller hardware.

If there cannot be more than one instance because of physical limitations, then global state is fine.   However, often it is more useful to be able to create multiple instances of the thing/facility; and then you cannot use global state.

Here is a practical example.  I love to use the Xorshift64* pseudo-random number generator, because it is extremely fast, and because if one uses only the 32 high bits of the result, it passes all randomness test in the BigCrush randomness test suite:
Code: [Select]
#include <stdint.h>

/* Xorshift64* PRNG state.
   To randomize the sequence, initialize to any nonzero value.
*/
static uint64_t  prng_state = 1;

static inline uint32_t  prng_u32(void)
{
    uint64_t  x = prng_state;
    x ^= x >> 12;
    x ^= x << 25;
    x ^= x >> 27;
    prng_state = x;
    return (x * UINT64_C(2685821657736338717)) >> 32;
}
I left out the randomizing function, because I like to use the Linux-specific getrandom() call for it, but one could also use POSIX clock_gettime() or even the C89 time() or BSD gettimeofday() for time-based initialization.

The above works, is very fast and very random (assuming you choose a random initial 64-bit seed, prng_state, as otherwise it obviously produces always the same sequence).

However, you only have one generator per process.

Let's say you have a multithreaded process, but you still need repeatable results (based on seeds for each thread or task at hand), so you cannot use one global pseudorandom number generator.  What to do?

Well, make it non-global, of course.  The first step:
Code: [Select]
typedef  struct {
    uint64_t  state;
} prng;
#define  PRNG_INIT(seed)  { .state = (seed) }

/* void prng_randomize(prng *g); -- omitted, because it tends to be OS-specific */

void prng_init(prng *g, uint64_t seed)
{
    if (g) {
        /* Note: zero seed is not allowed, so we replace that with 1. */
        g->state = seed | !seed;
    }
}

uint32_t prng_u32(prng *g)
{
    if (g) {
        uint64_t  x = g->state;
        x ^= x >> 12;
        x ^= x << 25;
        x ^= x >> 27;
        g->state = x;
        return (x * UINT64_C(2685821657736338717)) >> 32;
    } else {
        return 0;
    }
}
This way, in your own code, you just declare a random number generator you want to use, and initialize it to the desired seed,
    prng  mine = PRNG_INIT(1);  /* Seeded with 1 */
or equivalently
    prng  mine;
    prng_init(&mine, 1);
or randomized via
    prng  mine;
    prng_randomize(&mine);
and then generate the pseudorandom sequence using prng_u32(&mine) calls.

(It is straightforward to extend such a state structure to contain both the needed state, as well as a pointer to the generator function, so that one can choose the PRNG implementation at run time.  Since the high 32 bits of Xorshift64* beats even Mersenne Twister in randomness, I don't bother anymore, though.)

See how the concept of "state" generalizes?  It is quite intuitive, and functional approach to global variables.



A counterexample, and a common one seen in Arduino sketches:
Code: [Select]
int i;

void foo(void)
{
    /* ... */

    for (i = 0; i < 5; i++) {

        /* ... */

        bar();

    }
}

void bar()
{
    /* ... */

    for (i = 0; i < 15; i++) {
        baz();
    }

    /* ... */
}
The bug is obvious: whenever we call bar() from within the loop in foo(), the loop index variable gets modified, and thus the code does something completely different than what a straightforward reading of the code would indicate.  In this case, foo() will only call bar() once.

The key is to think about why this is a bug.  We've erroneously globalized the internal state of foo(), which then gets unexpectedly modified by a call to foo().

Apologies for the wall of text, but hopefully it was worth reading.  ;)
« Last Edit: October 27, 2022, 11:01:34 am by Nominal Animal »
 
The following users thanked this post: MK14, wek

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8179
  • Country: fi
Re: Global variables - Evil or not
« Reply #76 on: October 27, 2022, 12:57:22 pm »
Keep state as local as possible is a good general advice not limited to globals vs. locals.

I hate to see C code where all local variables are defined at the start of the function; especially if it's a bunch of loop variables, temporary variables of different types, etc. Even the older C standards allowed definition at the start of a block, and for a long time, variables can be defined in the middle of block (and inside the for loop initializer, for(int i = 0; ...))

This not only limits the scope of the variables, actually preventing bugs (because using the name elsewhere now just results in a compiler error about undefined name), but also makes code much more readable as you don't need to scroll far to find what is going on.

The same is about keeping static state. At least I went through the learning stages: first I just used global variables to keep state. Next I learned they don't need to be exposed globally, make them static. Later I realized I can put them inside function, if the use is limited to one function, limiting the scope to this function only. And last, I realized it doesn't need to be at the start of the function. Consider the differences in readability:

Code: [Select]
int uart_initialized = 0;

void initialize_uart()
{
    ... do things ...

    if(!uart_initialized)
    {
        ... things ...
        uart_initialized = 1;
    }

    ... things ...
}

Code: [Select]
void initialize_uart()
{
    static int uart_initialized = 0;
    ... do things ...

    if(!uart_initialized)
    {
        ... things ...
        uart_initialized = 1;
    }

    ... things ...
}


Code: [Select]
void initialize_uart()
{
    ... do things ...

    static int uart_initialized = 0;
    if(!uart_initialized)
    {
        ... things ...
        uart_initialized = 1;
    }

    ... things ...
}


Code: [Select]
void initialize_uart()
{
    ... do things ...

    // you can even limit the scope further!
    {
        static int uart_initialized = 0;
        if(!uart_initialized)
        {
            ... things ...
            uart_initialized = 1;
        }
    }

    ... things ...
}

 
The following users thanked this post: newbrain, MK14, uer166

Offline Buriedcode

  • Super Contributor
  • ***
  • Posts: 1613
  • Country: gb
Re: Global variables - Evil or not
« Reply #77 on: October 27, 2022, 05:41:51 pm »
Context:
1) I'm not a programmer I just dabble in C and c++ to a small extent.
2) Embedded application running on a smallish uC for example a small sub module in a automobile, for example: bool wipersOn = false;

I appreciate a global variable in some large program for some large company for example American Airlines would probably be a really bad idea.

The moment you google "global variable" half the comments are DON'T DO IT you will burn in hell.

I have used global variables forever and have never had any issues. Am I missing something?

There are two different issues:

1) static lifetime for a variable. This is absolutely necessary for statefull programming. Sometimes these variables may even need to be in EEPROM rather than RAM so they survive reset/power off.

2) too much visibility of a static variable, such that you can't easily know which parts of the program read and/or write to it.

Tools such as an IDE or even simply grep on the command line can help you find all the places a variable is used.

If a variable is used in a single function then it can be declared as "static" inside that function.

If a variable is used in a small number of functions then it and those functions can be gathered in a single C file and the variable global in that file but  marked as static. Other C files will then not be able to refer to it by accident.


In a small program none of this is a problem. The potential problems arise in large programs with poor modularity discipline.

I just wanted to double the visibility of this and highlight the point :)

Having worked on 8-bit MCUs with 1k program space, and at the other extreme on a team working on a large multi OS app, certain "rules" simply cannot be applied equally to both ends of that spectrum.
I suppose habits that are completely device/code/compiler independant such as variable naming conventions can cover almost every area, but as soon as it relates to architecture the differences are so great the number of sweeping generalisations diminishes.
 

Offline coppice

  • Super Contributor
  • ***
  • Posts: 8654
  • Country: gb
Re: Global variables - Evil or not
« Reply #78 on: October 27, 2022, 05:49:53 pm »
Having worked on 8-bit MCUs with 1k program space, and at the other extreme on a team working on a large multi OS app, certain "rules" simply cannot be applied equally to both ends of that spectrum.
I suppose habits that are completely device/code/compiler independant such as variable naming conventions can cover almost every area, but as soon as it relates to architecture the differences are so great the number of sweeping generalisations diminishes.
Oh, the same rules can be applied, and often are. Someone used to big software tries writing for a small MCU, fails to adapt and concludes the application just cannot fit. The project is cancelled. If someone more flexible later picks up the problem a product may be produced.
 
The following users thanked this post: MK14

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3147
  • Country: ca
Re: Global variables - Evil or not
« Reply #79 on: October 27, 2022, 06:07:28 pm »
Next I learned they don't need to be exposed globally, make them static.

You have to. But not all people know this. It is very easy for to put a variable into a .c file (as opposed to .h) and think that it is now hidden from the outside. And it is, sort of, true - the compiler which compiles other .c files doesn't see it. But the linker does. So, if someone has two .c files with a variable named "counter", the linker will map both to the same memory space, creating complete mess. To prevent this, you must use "static".

This confusion happens because for the compiler there's no difference whether something is in the .h file or .c file. The compiler doesn't know which part of the code is going to be exposed to other compilation units through the .h file, and which part is not. Hence, the rules for both .h and .c files cannot be different. If you put a variable into the .c file, the result is the same as if it was in the .h file. In contrast, pascal has two different sections - "interface" for exposed variables and "implementation" for anything local to the compilation unit. In C you must use "static".

If someone forgets "static" for a file-scope variable it will become gloabal for the linker. But this is unintentional. This doesn't affect the use of global variable when you really meant them to be gloabal.
 

Offline uer166

  • Frequent Contributor
  • **
  • Posts: 893
  • Country: us
Re: Global variables - Evil or not
« Reply #80 on: October 27, 2022, 07:42:16 pm »
Keep state as local as possible is a good general advice not limited to globals vs. locals.

You can go even further and say that state as a general concept is the root cause of a lot of complexity and some % of hard to reproduce bugs. I think in certain cases it's actually a good thing to centralize state (whether you make it all global or not), such that the system is easily observable, and all state is accounted for. Just imagine some power converter with a few control loops that use global V/I/PID state/Lead-lag state variables, but where each function is entirely state-less on its' own. To me that's a perfectly valid solution that doesn't bury scope of state to the point that it's hidden.

Idk why I'm still rambling on this other than to show that nothing a fit-for-all advice, and appeal to authority is not really a valid defense of any argument. Reducing total state space of a running program is a much more agreeable concept to most though, compared to globals vs. locals vs. shit and sticks.
« Last Edit: October 27, 2022, 07:44:37 pm by uer166 »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf