Globals in C

Go To Last Post
21 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have a confession to make. I use global variables all the time. I know, everybody says that its bad form, not proper OO programming, makes for difficult code maintenance, sets me up for disastrous problems and lots of other things too. But, I find them handy and easy to work with. I also know that all of the code that I write is ANSI C for embedded processors that no one else is ever going to look at, much less maintain. Most of the software is simple and straightforward, and global variables are very easy to work with. I realize that globals can be modified by any routine in the code, but that's the whole point of using them.

 

So, given the circumstances, what's wrong with them?

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jimlake wrote:
I know, everybody says that its bad form,

Says who?

 

I use global variables all the time as well, but my endorsement is not worth a hill of ants so take solace in my solidarity then smiley

 

Another Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Whether you use globals or not, the cpu doesn't care - it does what it is told. The major challenge of programming is a human one. We put the bugs in, so all these 'recommendations' are to make the code understandable to our feeble brains so hopefully what we want turns out to be what actually happens.
If your programs grow and you start having problems tracking down bugs, then you'll begin to understand the evils of globals. Until then, be blissful.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So, given the circumstances, what's wrong with them?

 

Nothing.  The case against globals was made when real serious professional computers started costing at $250,000 and had the capabilities of a $4 ARM processor. 

 

If you think of an AVR as a dumbed-down PDP-11 that manages to run C++ on a wing and a prayer, then you don't use global variables in your code. You do things right, like a professional is supposed to.  Meaning: no globals.

 

If you think of an AVR as steroid-enhanced TTL chip with delusions of grandeur, then you don't bother with the rules that guide the use of real serious professional computers.  It's just a programmable coffee-maker IC that costs 59 cents in lots of 1000.  Get a life, dude, globals? sure, whatever works.

 

This all changes in the next ten years as the computer that costs a million dollars in the year that you were born starts selling for $2, and compiles Arduino "shield" source code left over from the AVR without modification.  Then we all give up playing games, and start doing things right.

 

Until then,  your choice.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

so then what would be the RIGHT way to configure a variable that will be used in several functions then?

Jim

Edit:
A Google search of "Why are global variables bad" returns a wealth of great explanations. Makes me want to rethink a few things.

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

Last Edited: Wed. May 18, 2016 - 01:53 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can think of a number of reasons why I use a mix of global and local vars:

 

1. Globals take no stack space. Thus, a global's footprint is fixed and you do not have to guess about its impact on RAM

 

2. Globals do not require space as an argument on a stack going into a function call. That can impact both stack and speed.

 

3. If you DO want to mess with a value within a function, you do not have to mess with pointers.

 

4. You need globals to get values in and out of an ISR. They don't take any arguments and don't return any values.

 

5. Bet there are more good reasons

 

On the other hand:

 

1. If you use real local variables, such as an index in a for-loop, then implementing as a global (particularly jointly operated upon in an ISR) can be really hazardous.

 

2. Code portability is greatly enhanced when you use restricted-scope variables.

 

3. Bet there are more good reasons, here, also.

 

So, there are major trade-offs, no matter which way you choose. Sometimes, it will tilt one way, sometimes, the other. Problem is: it takes thought to do it smartly.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Wed. May 18, 2016 - 01:53 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think its a multimodule-multiprogrammer defense. Once the program gets too big for one guy, then there's the problem of one programmer stomping on another programmer's variable of the same name. Thats why the software engineers invented file scope and function scope and module prefixes for variable naming . Not so much of a problem for one programmer massaging how ever many modules fill up a mega1280 or 2560.

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A Google search of "Why are global variables bad" returns a wealth of great explanations. Makes me want to rethink a few things.

 

Yup, I recommend everyone does the same ~_o

 

p.s. for some reasons, no one else on this thread mentions that often local variables are allocated to CPU registers, and so does not take up any RAM, and your program will run MUCH faster.

 

But do that google search. There are too many things to list...

Richard Man http://imagecraft.com

Beyond Arduino - When you're ready to get serious...
JumpStart C Tools, The Better Alternative.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I dunno.  An embedded AVR project with "lots" of global variables is still likely to have fewer global variables than a desktop program that has "carefully avoided global variables as much as possible."

 

One of the things that replaces global variables in "real" programs is dynamically allocated memory from the heap, which embedded programmers avoid for number of other good reasons.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I guess that we take it for granted that you use local's for loops etc.

 

I'm surprised that nobody has mentioned static variables as a way to protect global's.   

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I swing both ways on this.

 

(but enough about me ... ;-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Globals are very useful. Locals have many benefits. Among them:

 

1. Locals are allocated from the stack, so if one function has 28 bytes of local variables, another function has 57 and still another 33, you don't have 118 bytes of ram used for them, but 57 bytes of stack. So long as these functions do not call each other and you don't make the variables static.

 

2. With local variables, you have less chance of corrupting one while coding something completely different by accidentally reusing a name. This kind of bug can cause hives, baldness, drunkenness and panic attacks.

 

As a long time programmer with degrees in software, I keep most variables local, using globals only for variables that need to be visible to multiple functions, or an ISR. Even then, I often mark the global static so I know code in some other part of the program doesn't accidentally mess with it. Oh, yes. This all goes haywire when you try to stick 5 characters in a string size 4. 

The largest known prime number: 282589933-1

It's easy to stop breaking the 10th commandment! Break the 8th instead. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When writing an avr program, your goals are: program works, program doesnt use all flash, program doesnt use all ram, program doesnt run too slow. A static local variable is nutty. Its still in the bss, so it doesnt save any space. If any other function needs to look at it, it might as well be global. Sometimes I copy global gcat gdog gbird to local lcat ldog lbird where they all get used in registers. If something needs to be saved, copy it back at the end. Did I invent that trick, or has it been around since Jan 1 1970 when the universe was created?

 

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think there's a huge difference between one guy in his back bedroom or on his workbench programming an AVR with just his code to do that job he wants it to do and a large commercial project on perhaps more extensive hardware with a team of 5/10/20/50 engineers working together in some huge collaborative project. It also will make a difference how later maintenance (bug fixing/feature addition/etc) will be done.

 

If you are one guy, you make the product, you sell it, later you have to read back your code and fix it or add the whizzy new feature everyone is asking for then to be honest you can do whatever pleases you inside the code. Write it as one big function if you like or whatever.

 

The issue arises when you then try to work together. 7 of your 50 engineers can't all claim a global variable called "count" for example ;-)

 

Also in such a project there's every chance that the people/team who do post-release maintenance are not the original authors. So those maintenance engineers need to be able to quickly pick up and understand what is going on in the code that some else wrote (they will hopefully have the benefit of design documentation of course) and to do that the code need to be written in a very modular/maintainable fashion. You want an "ADC" module or whatever that is virtually standalone and can be wired up to some kind of regression test harness in isolation from all the rest of the code if you plan to add or fix it and then test that nothing that was working previously is now broken by the change. Pulling such blocks out to work on them is not helped by reliance on shared global data.

 

Even if there are not separate maintainers, in the 50 man project there's every chance that after 5 years seventeen of those 50 have moved on to other companies and 27 of them have now been reassigned to the new "delta" development project so there's only a few of the original engineers left and the team is now mainly new interns who are just "learning the ropes" on existing project code. They need to be able to read/understand the code too.

 

In fact the whole raison d'etre and appeal of C++ is for exactly this kind of environment. It goes even further towards isolating code and data that has a specific function into a "private area" that cannot be influenced by anything outside of that area. Having said that C engineers that have been working in the 50 man project kind of environment will already have been writing VERY modular C code anyway making as much of the data and functionality as possible "static" and so on.

 

One thing that helps a lot are coding standards. If all 50 engineers are made to adhere to a common coding standard (layout, variable naming, etc) even with build tools that check the code for conformance, then all the code should "look" like it was written by the single engineer and when Fred takes over from Eric it's just going to look to him like something he might have written himself - so he more easily picks up what is going on and understands the operation because of the common look and techniques.

 

As this is an AVR8 message board where it is VERY unusual for more than one software engineer to work on a single AVR project then I guess none of this matters.

 

(but if you ever hope to move on to job in a large team it does help to understand the concepts and why "big" engineering is done the way it is done - books like Steve Macguires "Writing Solid Code" which come out of the environment of Microsoft's 27,000 software engineers highlight the lessons learned over the years in huge teams and why things are done the way they are. If I can find my copy I'll see if he has thoughts on global data ;-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In case anyone glossed over it in clawson's message:

Modularity helps testing.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Modularity helps EVERYTHING.

The largest known prime number: 282589933-1

It's easy to stop breaking the 10th commandment! Break the 8th instead. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But the big question is how to cut the modules:

1: By the HW

2: By the user functionality

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sparrow2 wrote:
But the big question is how to cut the modules:

Cohesion and Coupling are the key word here

 

https://en.wikipedia.org/wiki/Co...(computer_science)

 

https://en.wikipedia.org/wiki/Co...(computer_programming)

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

re: one-person project

 

Every month or so, we have a company emailing us for advice on how to rescue/compile a project that was done in 2000 with an ancient version of the AVR compiler. The original programmer is of course long gone...

 

 

Richard Man http://imagecraft.com

Beyond Arduino - When you're ready to get serious...
JumpStart C Tools, The Better Alternative.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Richard, i'm probably the cause of that! I did most of my AVR coding with your fine tools. Just last week i fired up the old XP machine to recompile some old code. V6.31 doesnt seem to like win7 64bit.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That is why I like to stay away from any tools with license checks - no problem using any gcc version on any version of Windows.

Last Edited: Mon. May 23, 2016 - 11:38 PM