Warnings about static declarations of functions and variables

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

Newbie.  Trying to learn about being complete in declarations and definitions.  Want to make sure to declare things static (for better compiler efficiency, is that the reason?).  But, when I do this, I get all kinds of warnings, although the program runs properly on the board.  Here's an example of a .h and .c and the warnings I get:

 

display.h:

# ifndef Display
# define Display

//	#pragma once							// what does this do?  Still needed with the ifndef?

	#include "IoPins.h"
	#include <avr/io.h>

	static char ButtonState;
	static char FlashLEDState;

	extern void DisplayInitialize();
	extern void DisplayUpdate();
	static void DisplayOn();
	static void DisplayOff();
	extern void getInputs();

# endif

 

display.c:

#include "Display.h"

extern void DisplayInitialize()
{
	ButtonState = 0;
}



extern void DisplayUpdate()
{
	if (FlashLEDState | ButtonState)
	{
		DisplayOn();
	} 
	else
	{
		DisplayOff();
	}
}


void DisplayOn()
{
	PORTB |=  (1<<LED01);
}

static void DisplayOff()
{
	PORTB &= ~(1<<LED01);
}

extern void getInputs()
{
	ButtonState = !(PINB & (1<<Button01));
}

 

warnings:

Warning    1    'ButtonState' defined but not used [-Wunused-variable]   

Warning    2    'DisplayOn' declared 'static' but never defined [-Wunused-function]   

 

 

Warning    3    'DisplayOff' declared 'static' but never defined [-Wunused-function]  

Warning    4    'ButtonState' defined but not used [-Wunused-variable]   

 

Warning    5    'FlashLEDState' defined but not used [-Wunused-variable]   

Warning    6    'DisplayOn' declared 'static' but never defined [-Wunused-function] 

Warning    7    'DisplayOff' declared 'static' but never defined [-Wunused-function] 

 

 

 

 

Now, I understand this is kind of a hokey little program snippet (and better ways to implement the functionality).  I'm just trying to get my arms around 'static' and 'extern'.  I don't understand the warnings, because they warn me of a variables that are not used (but, ar used) and functions that are never defined (but, I think they are, and they run on the board).  I don't know if I should just ignore these warnings, or I'm actually doing something incorrect.

 

On a side note, that #pragma once.  Is that needed if I'm doing the ifndef?  Or, are those doing 2 different things?

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

Any chance that you are somehow compiling just the include file by itself?

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

jl-dev wrote:
On a side note, that #pragma once.  Is that needed if I'm doing the ifndef?  Or, are those doing 2 different things?

 

You do know how to search don't you? wink http://en.wikipedia.org/wiki/Pragma_once

 

About your use of "extern" for function prototypes and function definitions, well, you need to read this http://en.wikipedia.org/wiki/External_variable

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
	static char ButtonState;
	static char FlashLEDState;

Whey are you defining variables in a header file? Surely you only want extern declarations in a .h with the actual definition in a .c but if they are "static" you wouldn't be exporting them anyway (which is kind of the whole point of "static" in this context!).

 

The rules about what you put in a .h are pretty simple and basically boil down to: "if you were giving a binary copy of the code to someone else and all they could "see" was the .h what would they need to know to be able to make full use of your code?". For sure they would not need to know about any "private" static variables you might happen to have in your implementation. They won't be interested in accessing your "ButtonState" or "FlashLEDState". In fact you almost certainly don't want them to even know they exist. You don't want those mentioned in the .h file - keep them "private" within the .c file.

 

(later when you move from C to C++ you'll actually come across "public:" and "private:" which more formally dictate these things).

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

Clawson,

 

Thanks!  Moving those 'static' down to the .c file eliminated the compile warnings ...

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

jl-dev wrote:
declare things static (for better compiler efficiency, is that the reason?).

No, that is not the primary reason - though it may be a side-benefit.

 

You can look up what 'static' does in you 'C' textbook - it limits the scope of the identifier to the current Compilation Unit.

 

But, if you define a 'static' variable in a header, and #include that header in multiple source files - that means you'll get a separate, independent instance of the variable for each 'Compilation Unit' in which it appears!

 

Note that this is standard 'C' stuff - nothing specifically to do with Atmel Studio.

 

Some 'C' learning/reference resources: http://blog.antronics.co.uk/2011...

 

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...
Last Edited: Tue. Jan 27, 2015 - 11:46 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No, that is not the primary reason - though it may be a side-benefit.

Agree - outside a function it means "this variable only used in this file". This does give the optimiser opportunity to discard or optimize access it might not have had if it thought some other compilation unit that might be linked in later could also need to access it. But the optimization thing is more of a benefit than the true intent of using it.

 

But as awneil says the principal use of static is to keep things "private". It's saying "no one outside this file ever needs to know this variable exists". One use would be if you had both a timer module and an ADC module and they both wanted a (file global) variable called "count". Each could have a "count" and the linker would not be confused about there being two things of the same name when it links together timer.o and adc.o

 

Of course if you use something like:

static const int max_volume = 37;

a further benefit of the static here is that by saying "this is private to this file" and the const saying "this is an unchanging value" the compiler does not actually need to create a location in memory called "max_volume" and stuff 37 into it. So when you write:

if (vol > max_volume) {
    vol = max_volume;
}

the code here will not be going off to memory to pick up 37 from a location called max_volume. The compiler can basically treat this as if you had written:

if (vol > 37) {
    vol = 37;
}

So a "static const" is a bit like a:

#define MAX_VOLUME 37

in this sense but the difference from a pre-processor define is that it has a type (int in this case).

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

clawson wrote:
the const saying "this is an unchanging value"

 

You're talking C++ here?

 

In 'C',  const just tells the compiler to disallow writes to the object - it does not mean that the value is unchanging!

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...