#define versus const byte

having read all the similar posts, I still have a question. Using the following two methods of asigning pin values (just to be clear, one or the other, but not both at the same time), they both compile fine. The problem is, I expected the "const byte" method would result in global variables in dynamic memory of the Pro Mini (in the compiler report) to be 14 bytes bigger than the "#define" method. Nope, they are exactly the same.

// the following are definitions used to avoid global variables --------------------
#define led13 13 // on board LED
#define studio_heater A0
#define shop_heater A2
#define shop_fan A3
#define studio_flow 2 // radiant flow meter
#define studio_hot 4 // radiant water temp
#define shop_temp 5 // at the table saw
#define shop_hi 6 // at the ceiling fan
#define plants 7 // plant shed temperature

#define up_k 8
#define dn_k 9
#define pg_k 10
#define st_k 11
#define en_k 12

// the following are global variables ----------------------------------------------------------
const byte led13 = 13 ; // on board LED
const byte studio_heater = A0 ;
const byte shop_heater = A2 ;
const byte shop_fan = A3 ;
const byte studio_flow = 2 ; // radiant flow meter
const byte studio_hot = 4 ; // radiant water temp
const byte shop_temp = 5 ; // at the table saw
const byte shop_hi = 6 ; // at the ceiling fan
const byte plants = 7 ; // plant shed temperature

const byte up_k = 8 ;
const byte dn_k = 9 ;
const byte pg_k = 10 ;
const byte st_k = 11 ;
const byte en_k = 12 ;

please post your code in code tags.

The compiler does quite a good job and optimizes values which don't change / constants.

by the way, I would use uint8_t as this is used internally:

show sketch what you tested.

In that case, why is it so common around here to see #define for numeric values rather than const byte or whatever?

I don't believe it's necessarily the novices I see that are using #define.

Like your mother told you .... just because your friends are jumping off a bridge doesn't mean you should jump off a bridge.

1 Like

Because the const construct is several decades newer than #define. The #define construct has been around since the beginning of C and was the only game in town.

The # define just does a text substitution by the preprocessor. The const construct defines a data type and value that is invariant, which the compiler can type check and optimize.

6 Likes

The const construct defines a data type and value that is invariant, which the compiler can type check and optimize.

That is why I use const.

It's not just about bad habits.
The applications of the #define are much broader than just defining constants; a definition can contain operators and entire procedures.
An important advantage of #define macros as constants is that it can be used in conditional compilation directives, which makes the code more flexible and reduces the size after compilation.
Constants, before the advent of constexpr, could not be used for this.

That is actually a good question. "Old habits die hard".

Although writing code is nominally engineering, there is a lot of "folklore" around. A lot of things that used to be true which no longer are, and many things that were never true in the first place, get blindly repeated as "best practice".

Unfortunately you get the same effect in professional environments, so it is not just novices.

1 Like

Well, since you put this on your profile,

Please do not PM with technical questions or comments. Keep Arduino stuff out on the boards where it belongs.

We have no choice but to respond here. I'm no saint here, but I think invective aimed at the 'forum in general' needs to be responded to, not ignored.

I think that while this is factually correct, it needs to be mitigated with a follow-on statement by the author, something like,

To try to mitigate this, I will write a really good Tutorial, without invective, including a bit of history about the usage, and advising about 'still acceptable' and 'no longer acceptable' use cases. I'll go away and write it now, so stay tuned...

Otherwise, it just comes off as "I know better than the rest of you slobs, but I'm not sharing the cookies". Apologies, @Delta_G , but your statement was a bit off-putting. We all have our blind spots; I surmise many contributors here learned C, to varying degrees, before you were born. Statements like yours will leave many helpers feeling like they're unwelcome; frankly, my first response was "Okay, we'll let @Delta_G carry all the weight from here, if he's so good; honey, grab the popcorn!". That's not helpful, either, though.

Not your intent, I'm sure, but I also don't see you regularly mentoring (in a positive way) about the uses of #define (or the other "common bad practices") (perhaps I've just not been watching closely enough), so it's a bit 'rich' to now bad-mouth the forum as a whole about this.

Many of those 'bad practices', by the way, come directly from their wholesale use in Tutorials, Examples, etc. etc. How in hell is a novice to judge that the learning material is flawed? They use what they see, dimly perceiving(at best) that it must be 'correct', because it does compile. Maybe, you could volunteer to produce or update one or more Tutorials monthly, utilizing your vast knowledge of cutting edge best practice C++ techniques to pull the forum into the 21st century?

That is not sarcasm, by the way, but rather a plea. This forum is, and always will be, a reflection of it's members - in the whole - and the help they've given. If we withhold information, it serves no useful purpose; but how we provide it is also important. The constant braying some do in individual threads is irritating, but understandable. Pointing to tutorials is more useful, IMHO, provided those tutorials contain true 'best practices'. Looking 'down your nose' at the 'smelly beginners' is most un-useful.

To put it another way, the horse can't drink if you don't lead him to the water; whether he does drink when you do so is a reflection of the water's quality, the horse's intelligence, and the horse's thirst; but first he must have it in front of him. While we have no control over the intelligence or thirst parameters, we have a lot of influence over the quality of the water, and the gentleness with which we lead him to it - so stop pissing in the river, and put away the hammer.

Posted in the hope of improving the forum. I will not be responding to reply-hate, nor will I engage in a debate about this. Your post exposed your opinion, this post exposes mine, and we're neither likely to change.
Best wishes this holiday season.

2 Likes

one way const in combination with typedef could have been helpful ... could have ... is that the compiler would issue an error when a sym of some type is being used when a symbol of a different type is required, which is what some other languages enforce.

in other words, const MyType A = 3 could not be used as a value to HisType x = A or as a function argument required to be HisType;

I learned C, to a varied degree, before many of the ppl coming here for help were born to any degree.

I use and will continue to use # define for manifest constants and sometimes for an occasional bit of maths.

Fire me.

Except I don't work for you, nor anyone who makes me do things any particular way. I try not to swim upstream, naturally, but neither am I in the straight jacket the programming bros wear at their high paying jobs. You've seen it here, ppl who just have the style manual more than memorized and are incapable of not doing things just the way the ppl they dressed like and followed around for years.

I understand all the points about best practices and stuff, but this is not Google or Microsoft and we aren't talking about millions of lines of sometimes arguably very mission critical software.

Since define will show up in code for the foreseeable future, I have no problem exposing b]noobs to it. It is the simplest way to introduce a simple idea, the capability to say once that N_NERDS is just going to get textually replaced everywhere it is seen with 42.

That this capability is afforded with no language features being used like const byte N_NERDS = 42; is a benefit to seeing it first. Simple text substitution, like an improvement on global search 42 and replace with 43 especially if there are other 42s running around unprotected.

Leave to someone else the need to side track more than that simple explanation, and talk all about the modern fashions. To me it is just one more thing to learn at an appropriate time.

a7

const int nCars = 1.5;

it's too bad the compiler doesn't flag this as an error.

but it should certain draw a query from a reviewer. "if nCars is an int, how can there be .5 cars"?

LOL. Now there is a contributor I can honestly say I miss from time to time. For all the wrong reasons.

a7

As world´s best tinker standard.

btw

What is the functional difference between the declaration using either const or constexpr?

I am receptive to suggestions for improvements towards best practice for the code in any of my tutorials. Keep in mind that I consider myself to be a reasonably good hobby programmer in C (not so much C++). Happy to receive constructive criticism by PM.

I will consider any serious request to unlock any topic so comments can be added. Generally requests from regular posters to unlock topics get granted. I think the other mods will also do the same.

1 Like

Unlike const , constexpr can also be applied to functions and class constructors.

and

The primary difference between const and constexpr variables is that the initialization of a const variable can be deferred until run time. A constexpr variable must be initialized at compile time.

See https://learn.microsoft.com/en-us/cpp/cpp/constexpr-cpp?view=msvc-170

P.S.: Also interesting ...

A constexpr function is one whose return value is computable at compile time when consuming code requires it. Consuming code requires the return value at compile time to initialize a constexpr variable, or to provide a non-type template argument. When its arguments are constexpr values, a constexpr function produces a compile-time constant. When called with non-constexpr arguments, or when its value isn't required at compile time, it produces a value at run time like a regular function. (This dual behavior saves you from having to write constexpr and non-constexpr versions of the same function.)

1 Like

I think the very big difference is that constexpr is checked regarding its type and use while #define is just a preprocessor (word processor) macro.

So using constexpr (or const) is more safe than #define ...

There is obviously a difference between constexpr functions and constexpr variables as variables are only accepted as constexpr if their value can be assigned at compile time.

May be this link is of interest for you where someone wrote down his/her view about it:
https://www.vishalchovatiya.com/when-to-use-const-vs-constexpr-in-cpp/

2 Likes

No worries ... :wink:

I just found this and it may be an even better explanation:

https://www.geeksforgeeks.org/understanding-constexper-specifier-in-cpp/

E.g.:

Have fun!

1 Like