Using a constant defined in the header file

First off, I want to make it clear that I mostly don't know what I am doing. I have managed to modify an existing library for a VFD to work with a different VFD that I have. I have everything working to my satisfaction, but am having trouble with one function that I created.

In the header file, some constants are defined. I simply added the ones I needed after the existing constant definitions.

class NoritakeT300A : public Print {
public:

// This was existing. I added the 5 below.
  static const uint8_t CURSOR_SET_CHARACTER = 0x1B; 

  static const uint8_t BRIGHTNESS_PREAMBLE_CHARACTER = 0X04;
  static const uint8_t DIM = 0x20;
  static const uint8_t MID1 = 0x40;
  static const uint8_t MID2 = 0x60;
  static const uint8_t FULL = 0xFF;

In the cpp file, we have this function which I created.

void NoritakeT300A::brightness(uint8_t level)
{
  writeInternal(BRIGHTNESS_PREAMBLE_CHARACTER);
  writeInternal(level);
}

In my ino demo file, I am calling the function from within loop().

vfd.brightness(DIM);

I get the following error.

Brightness:38: error: 'DIM' was not declared in this scope

If I instead call the function this way, it works.

vfd.brightness(NoritakeT300A::DIM);

I sort of understand that adding the class name forces the program to use the constant that is defined there, but I don't understand why it isn't visible already. I obviously don't fully understand the use of Public declarations within a class and their scope.

So, please dumb down your explanation, so that I can understand what the problem is. More importantly, please tell me specifically how to fix this.

Thanks.

I'm not sure why, but I when I replaced the static const definitions in the header file with #define, the sketch worked without needing the class name prepended.

Can someone enlighten me?

The reason why sometimes you have to use

NoritakeT300A::DIM

instead of

DIM

is because different libraries and classes may have their own DIM. Which means that the compiler does not know which one to use. However if you use

NoritakeT300A::DIM

the compiler knows exactly which DIM to use. It also tells the compiler where to get it (inside NoritakeT300A)

mojoehand:
so that I can understand what the problem is.

Why do you consider it a problem? I consider it a problem if a library steps on the namespace of the sketch. The way it is now the user can use your library and have their own variable named DIM if they want with no conflict.

mojoehand:
More importantly, please tell me specifically how to fix this.

You can move the declaration out of the class. Better would be to put it in a namespace n in the .h file and then add using namespace n to your sketch which will allow you to access it as DIM but still keep the library friendly for others.
For example in the .h file:

namespace NoritakeT300ANamespace{
static const uint8_t DIM = 0x20;
}

class NoritakeT300A : public Print {
public:

// This was existing. I added the 5 below.
  static const uint8_t CURSOR_SET_CHARACTER = 0x1B;

  static const uint8_t BRIGHTNESS_PREAMBLE_CHARACTER = 0X04;
  static const uint8_t MID1 = 0x40;
  static const uint8_t MID2 = 0x60;
  static const uint8_t FULL = 0xFF;

example sketch:

#include <NoritakeT300A.h>
using namespace NoritakeT300ANamespace;
void setup() {
  Serial.begin(9600);
  while (!Serial) {};
  Serial.println(DIM);
}

void loop() {
}

mojoehand:
I’m not sure why, but I when I replaced the static const definitions in the header file with #define, the sketch worked without needing the class name prepended.

Because the define isn’t in the class so it’s the same as I have described above, only even less user friendly since you’re using the preprocessor.

Thanks for the explanation. I will try using a namespace.

When you define a class member as static this means that all instances of that class will share a single static copy of that property or method. There can only ever be one of them no matter how many instances of the object you instantiate. There is no instance associated with a static member because every one of them must share it. Because there is no instance you can follow to reference the member, due to the fact that all instances share the same one, you must specify the class explicitly to locate it. Other members of the same class need not specify the class name because it is a member of their class and so the default is to look for a local class member to resolve a reference to it. But when you want to access it from outside the class, you don't have an instance you can use to get at it because it is static. Therefore you gotta say where it is. Statics are not members of individual class instances, they are members the class as a whole.

When you changed it to a preprocessing definition using #define, you removed the static attribute and also moved it into the global scope. Thus there was no longer a need to say where it is. You could have also just made them global constants or even global static constants like so:

in .h file:
...

extern const uint8_t DIM;
     - or -
extern static const uint8_t DIM;

class NoritakeT300A : public Print {
...



then in cpp file:
...

const uint8_t DIM = 0x20;
     - or -
static const uint8_t DIM = 0x20;

...

Do this and you would not have to specify the class either since it is not a member of any class and exists in the global scope which is known everywhere. So vfd.brightness(DIM); will work just fine there too.

Using defines is generally preferable for this sort of thing unless there is a compelling need to tie them specifically to a particular class. For example to avoid possible namespace conflicts as pointed out by pert. Using defines reserves no memory for the value since it gets directly substituted in during preprocessing and the name of it (DIM in this case) never makes it into the preprocessed source that eventually gets compiled. It just shows up there as a hard coded number everywhere you used it.

When you choose const definitions instead you actually reserve a memory location for it and the object code will link to that address at runtime to determine its value whenever it gets referenced. In simplified technical terms, a define forces the code to use immediate addressing when it is referenced, const forces it to use indirect addressing.

A const is pretty much just like a regular variable without const except the compiler will bitch at you if you try to assign a new value to a const. So it designates a variable as a variable which the compiler will prevent you from changing elsewhere in the code. Otherwise it is the same as a variable. Define removes the variable completely from the equation and just directly substitutes in the definition at the point of reference as if it had been hardcoded there...thus using no memory for it. Actually you end up using more space for code as a trade off for using less data space when the #define is more complex than just a number.

Due to the limited supply of memory in these microcontrollers, it doesn't make a lot of sense to reserve memory for things that never change unless you have a good reason for doing it. So I recommend using #define nearly all the time and then deal with namespace conflicts (frankly a relatively rare thing) by simply changing the name of the thing. If you name things a little more uniquely than DIM, which I suppose could be a name easily chosen by some other library author, then you should not have to worry too much about that. For instance, calling it NT300A_DIM is not nearly as likely to be used by anybody else and cause a conflict down the road somewhere.

Hope that was understandable.

Yes, I mostly followed what you were saying. I appreciate the detailed explanation.

So, which does namespace use, program or data memory?

BTW, using namespace worked just fine.

Well if you put a const in the namespace it will use data. Defines are independent of namespaces since the name of the thing is discarded during preprocessing. All a namespace does is separate things which may have been given the same name so they can be distinguished. You cannot have two variables in the same scope using the same name. Namespace provides a means to delimit a scope in such a way that this conflict won't occur even when things are given the same exact name. It then forces you to specify which namespace you want to get the thing from so there can be no confusion about which one you're talking about.

I never had a need to use namespaces so I'm probably not the best one to explain them to you beyond that. I avoid the overhead by simply picking names that are sufficiently complex enough for me to be comfortable that name conflicts won't probably happen. And if they do, I just rename things to fix it. Just seems easier to me is all. Maybe I'm missing out...who knows?

I like keeping things as simple as possible. Somebody modifying your code sometime in the future may not understand what namespaces are, and thus it will make their job more difficult if you use them. So why do it if it is not necessary? It only complicates the code for no good reason. That's how I view it anyhow. I suppose if you are developing a general purpose library that lots of people will be using for all sorts of different projects, then it makes sense to wrap it all up in a namespace just to be safe and therefore insulate all your users from the potential headache of a name conflict.

Have you considered extending the class by creating a new class that inherits from NoritakeT300A? I’ve used this approach a few times now to add functions to display libraries. I believe that would make your constants accessible, and allow you to implement new functions seamlessly.

If I’m not stretching my memory too much, I think it would also allow you to add the constants to the .h file of the child class, thus allowing you to use the parent class without any modifications (usually a good thing).

Being a newbie, I have no idea how to extend the class, as you have suggested. For now, the use of namespace seems to be the best solution. It allows me to use the constants and avoids possible collision with similar names in other modules.

Personally, my approach to #define is to only use it if I need it for the preprocessor or certain cases where I can't use a const. There are tons of discussions of the reasons why const is better than #define so I see no reason to repeat that here but I thought looking at the memory usage of my example code might be relevant: NoritakeT300A.h

namespace NoritakeT300ANamespace{
static const uint8_t DIM = 0x20;
}

NoritakeT300A.ino

#include "NoritakeT300A.h"
using namespace NoritakeT300ANamespace;
void setup() {
  Serial.begin(9600);
  while (!Serial) {};
  Serial.println(DIM);
}

void loop() {
}

Compiled for Uno w/ IDE 1.6.8:

Sketch uses 1,982 bytes (6%) of program storage space. Maximum is 32,256 bytes.
Global variables use 200 bytes (9%) of dynamic memory, leaving 1,848 bytes for local variables. Maximum is 2,048 bytes.

Now using #define: NoritakeT300A.h

#define DIM 0x20;

NoritakeT300A.ino

#include "NoritakeT300A.h"
void setup() {
  Serial.begin(9600);
  while (!Serial) {};
  Serial.println(DIM);
}

void loop() {
}
Sketch uses 2,122 bytes (6%) of program storage space. Maximum is 32,256 bytes.
Global variables use 200 bytes (9%) of dynamic memory, leaving 1,848 bytes for local variables. Maximum is 2,048 bytes.

The #define version is actually using more flash because DIM is being treated as an int. You might say it's an unfair comparison but this demonstrates one of the benefits of using a const, there is actually a type. So let's cast to eliminate that difference: NoritakeT300A.h

namespace NoritakeT300ANamespace{
static const uint8_t DIM = 0x20;
}

NoritakeT300A.ino

#include "NoritakeT300A.h"
using namespace NoritakeT300ANamespace;
void setup() {
  Serial.begin(9600);
  while (!Serial) {};
  Serial.println((uint8_t)DIM);
}

void loop() {
}

Compiled for Uno w/ IDE 1.6.8:

Sketch uses 1,982 bytes (6%) of program storage space. Maximum is 32,256 bytes.
Global variables use 200 bytes (9%) of dynamic memory, leaving 1,848 bytes for local variables. Maximum is 2,048 bytes.

NoritakeT300A.h

#define DIM 0x20;

NoritakeT300A.ino

#include "NoritakeT300A.h"
void setup() {
  Serial.begin(9600);
  while (!Serial) {};
  Serial.println((uint8_t)DIM);
}

void loop() {
}
Sketch uses 1,982 bytes (6%) of program storage space. Maximum is 32,256 bytes.
Global variables use 200 bytes (9%) of dynamic memory, leaving 1,848 bytes for local variables. Maximum is 2,048 bytes.

Well I'm no expert programmer and there may be other situations where const causes more memory usage than #define but I just wanted to point out that it's not always clear cut that #define will save memory. Either way you go that 0x20 has to be somewhere.

Great point pert! I’ll just repeat that you don’t save memory using either. Its a trade off between code space vs. data space. With #define the resource itself (the value) gets scattered all over the code wherever it was used. This makes the code bigger since a copy of the value becomes part of every code instruction that used it, but makes the data usage smaller since you aren’t using it at all. Run time plays a part in the decision too. You gain a few clocks using #define.

I must also note that #define is far less safe. By today’s standards, I would say not safe at all.
Example:

// Header1:
#ifndef Boat_h
#define Boat_h

#define DIM 0x20

class Boat
{ ...
};
#endif

// Header2:
#ifndef Car_h
#define Car_h

#define DIM 0x40

class Car
{ ...
};
#endif

// Main
#include "Boat.h"
#include "Car.h"

dimTheCar( DIM ); <--- DIM is 0x40

// Reverse the #includes...
#include "Car.h"
#include "Boat.h"

...
dimTheCar( DIM ); <--- DIM is 0x20
...

The compiler won’t bitch cuz you are talking to the preprocessor not the compiler using #define. It doesn’t care if you give names a different value. There are no constant #defines. In fact, it’s a preprocessor feature to redefine things. Lots of times where it’s sensible to make preprocessing work. Particularly for multiple platforms. When it hits the 2nd def from the 2nd header, it does not crap out. It simply changes the value to the 2nd value & starts substituting that one from then on (until it changes again). The compiler never sees this cuz when the code gets there all names have been discarded. The compiler has no idea there are two defs. It has no idea if there are any defs. It thinks there are none. It only sees numbers plugged into the instructions.

This behavior means the compiled code will be functionally different depending on the ordering of #includes. Catastrophic news. And quite hard to locate, plowing through a lot of libraries…assuming you even notice it.

The IDE does not protect you from yourself when you use #define. You really have to be diligent about creating unique names.

Naturally when you type a variable & make it const, the code makes it to the compiler intact names & all & so it is able to protect you from using it incorrectly. Plus, as pert said, you can type the data to use less space sometimes.

Another memory factor is how often the thing gets used. When you use a const or a variable it always takes up the same predictable amount of space. One unit of whatever datatype. In the code where it is used, you end up with memory addresses getting substituted in place of names. Using it all over the place doesn’t cause any extra resource usage since the resource itself exists only in one place. For #define whatever you define just gets plopped in directly replacing the name. At runtime the processor is able to use immediate mode to get the value (it is part of the code now so no need to poll memory). This is faster to execute, by the way. But if you #define something complex, & then use it generously, you end up with lots of repeated copies quickly adding up to more than a single memory slot uses. It shows up in the code space not the data space, but total memory usage will be more with #define in that case. Basically you are spreading copies of the resource all over the place. It exists everywhere it is needed. The more often you need to use it, the better it is to stay away from #define. But if you only use it in a single file in a couple of places, the difference will be negligible & maybe even a tad less memory used. On a platform like Arduino, this is the more common thing you will see simply because the code cannot be physically large. Tight resource limits keep the code small & simple & therefore way less likely for this decision to have a significant impact. If it isn’t significant, you can safely ignore it.

We have devolved now into one of those areas where it is really up to the coder to decide how reliant on the compiler he is going to be. In the old days compilers didn’t do much more than translate. If we wanted a constant there was no preprocessor & therefore no #define. There was no const, only variable variables. If you wanted a constant you had to make a variable & then never make the mistake of changing its value ever. You can still do that, but nowadays you get lots of options like const which basically allow you to ask the compiler to do some of your thinking for you. I dislike relying on computers to think for me. Mainly because they are such astonishingly stupid things. They only do precisely what you tell them…never what you don’t. Even when it’s obvious. You can write this line anywhere:
1 == 0;
The computer won’t even blink. It’s too damn stupid to reason it out. It just says “false” & moves on. A person looking at that will be like WTF is this doing here??? It may be able to think orders of magnitude faster than I can, but even the most moronically simple nonsense I can conjure will be orders of magnitude more reasoned than anything it thinks up in 1/10000 the time. I am uncomfortable relying on such a brain to decide how I am or should be implementing my solution. In fact, most of the frustration people endure when dealing with compilers, & there never existed a person who didn’t, is due to the fact that the computer is too fuckin stupid to figure out what you’re telling it. Because you just aren’t being clear enough for its feeble mind to grasp. Nobody has told it how to handle vagueness, so it doesn’t. Stupid.

My attitude is the best way to avoid relying on the compiler to keep you from programming like a dumbass is to learn not to program like a dumbass. Not to rely on an idiot to point out your mistakes. In the end you will be a better programmer if you tend to prefer doing things yourself. I’ve been a programmer since 1977. We had almost nothing to help us back then. Learning in that environment made me adept at things like name conflicts. Today, I don’t need help with that…I got it wired so I don’t concern myself with it. I don’t think I have ever once sat down & said “I’m going to need a namespace for this” before I start…or even later on. I’ve run into them, but just never had a need to use them. Cuz I don’t write dumbass code anymore.

Actually in my own code I like static const class members because it forces me to be clear about using them & it isolates them from the rest of my code. For that class, all the instances will have a unique understanding of what DIM means. Outside, I must clearly specify which version of DIM I want because I’m obligated to use the ClassName::DIM syntax to use it. If there’s another class with the same name in it, then when I want the second one… ClassName2::DIM makes it clear. I really use that feature for readability & maintainability reasons rather than as a crutch for not thinking things through completely. I get the crutch as a bonus I suppose, & I don’t complain, but it ain’t why I choose that feature. I like it cuz it requires clarity must be employed…something the machine is fond of.

Another bonus using static members–if you ever need the value of the constant (you always forget after awhile), it is plain where to go & find it. With #define there’s no telling where the thing comes from & brute force plowing through files is the only way. Its stuff like that I’m eager to rely on the moron to help me find. It is a stupid task perfectly suited for a idiotic brain to handle.

In the end, the method you like most is nearly entirely programmer preference. In a professional setting you have to think professionally & know all the ins & outs of clarity, reusability, maintainability, reliability, resource management, scaling, performance, etc. But in a place like this, where you don’t even have enough memory present on the platform to make anything really complicated, then you can get away with doing it any way you want as long as it does what you need & you understand it. The more complex you make it the more likely you will run into a shoe horning issue with memory space. In this place simpler is better, smaller is better. And #define is very simple. Therefore I think it is proper to use it pretty freely. If you run into problems, you can always add complexity, believe me that is trivial.

By the way pert, you probably have forgotten that you can type a #define by writing:
#define DIM (byte)0x20;
Then you get bytes instead of ints.

mojoehand:
Being a newbie, I have no idea how to extend the class, as you have suggested. For now, the use of namespace seems to be the best solution. It allows me to use the constants and avoids possible collision with similar names in other modules.

It’s easier than it sounds. The meat of it is in the constructor. Once you get the hang of it you will never go back.
.h:

// LedSegment.h
//
//************************************************
// extend LedControl to add a few custom conveniences
//
//************************************************

#include <Arduino.h>
#include <LedControl.h>
#include <avr/pgmspace.h>

#define SEMICOLON 0x09
#define HYPHEN 0x01
#define BLANK 0x00

class LedSegment : public LedControl
{
  public:
    LedSegment(int dataPin, int clkPin, int csPin, int numDevices);

    void init();
    void setIntensity(byte bright);
    void print2digits(byte device, byte pos, byte val, byte leadingZero, byte decimal);

  private:
    int numOfDevices;

};

// end class

.cpp:

#include <LedSegment.h>

//************************************************
// extend LedControl to add a few custom conveniences
//


// constructor:
LedSegment::LedSegment(int dataPin, int clkPin, int csPin, int numDevices)
  : LedControl(dataPin, clkPin, csPin, numDevices)
{
  numOfDevices = numDevices;
}


void LedSegment::init()
{
  for (int i = 0; i < numOfDevices; i++)
  {
    shutdown(i, false);
    LedControl::setIntensity(i, 0);
    clearDisplay(i);
  }
}

void LedSegment::setIntensity(byte bright)
{
  for (byte i=0; i<numOfDevices; i++)
  {
    LedControl::setIntensity(i, bright);
  }
}

void LedSegment::print2digits(byte device, byte pos, byte val, byte leadingZero, byte decimal)
{
  setDigit(device, pos, val%10, decimal);

  if (val < 10 and not leadingZero)
    setRow(device, pos+1, 0);
  else
    setDigit(device, pos+1, val/10, false);
}

// end of class definitions

AxeMurderer: Actually in my own code I like static const class members because it forces me to be clear about using them & it isolates them from the rest of my code. For that class, all the instances will have a unique understanding of what DIM means. Outside, I must clearly specify which version of DIM I want because I'm obligated to use the ClassName::DIM syntax to use it. If there's another class with the same name in it, then when I want the second one... ClassName2::DIM makes it clear.

I agree that's the best way to do it but mojoehand wanted a way to avoid having to specify the class when using DIM in the sketch so I thought using the namespace would be a reasonable way to achieve that without creating the potential for conflicts for other users of the library. I actually have used the namespace system in my own libraries before for strings because I haven't found a way to put them in the class, though there's probably a way to do it I just don't know about.