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

0 Members and 1 Guest are viewing this topic.

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19593
  • 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: 4068
  • 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: 19593
  • 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
 

Online langwadt

  • Super Contributor
  • ***
  • Posts: 4450
  • 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

Online peter-h

  • Super Contributor
  • ***
  • Posts: 3717
  • 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

Online uer166

  • Frequent Contributor
  • **
  • Posts: 895
  • 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.
 

Online peter-h

  • Super Contributor
  • ***
  • Posts: 3717
  • 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: 11692
  • 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
 

Online peter-h

  • Super Contributor
  • ***
  • Posts: 3717
  • 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
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6285
  • 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: 11692
  • 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: 3148
  • 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

Online newbrain

  • Super Contributor
  • ***
  • Posts: 1721
  • 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: 4068
  • 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: 11692
  • 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: 825
  • 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: 3148
  • 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: 825
  • 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: 11692
  • 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
 

Online uer166

  • Frequent Contributor
  • **
  • Posts: 895
  • 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: 825
  • 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: 19593
  • 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
 

Online newbrain

  • Super Contributor
  • ***
  • Posts: 1721
  • 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: 4046
  • 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


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf