One thing that will make a difference is that there is not a single Serial.print() function but a number of them. Which one is used depends on the data type being printed so I would expect different results from some different data types
For const values, which is best #define or const uint8_t ?
UKHeliBob:
One thing that will make a difference is that there is not a single Serial.print() function but a number of them. Which one is used depends on the data type being printed so I would expect different results from some different data types
OK, I thought Serial.print() isn't the optimal example here, so that explains a lot.
I shouldn't use Serial.print() as a test tool in the first place.
Then the original rules of data size are the same if we use one function and not overloaded function.
Thanks that's also an important point.
But since Serial.print() isn't the right tool to test data sizes, then I would just take with the fundamental rules of data sizes.
So as sizes issue is cleared now, then my last concern here is what to use in my libraries ? #define or const uint8_t ?
#define is used by the preprocessor to do what amounts to a text substitution, before invoking the compiler.
The const is processed by the compiler, so there will be type checking and possible generation of warnings or errors if applicable.
If you look at the amount of dynamic memory (RAM) used for each of your tests, that does not change because of the compiler optimizations hard coding the const values into the code, so there is no disadvantage to using const in terms of RAM usage.
You do need to be careful when choosing types, one of your test const values will not produce the expected output.
TheMemberFormerlyKnownAsAWOL:
You should use const.
I thought so, because with const I can control the size of the value, defines are 2 bytes.
But also I found something also interesting, when I define a value that is larger to fit in 2 bytes, then compiler adjust the size of define to be 4 bytes but also it's signed.
So if I even needed something that's bigger than 2 billion, then I should use long long which provides 8 bytes.
So eventually, this is not a one route that's the only route. Using defines or const either one of course works and right.
But for more optimized program space and with conclusions of this thread, and some search, it's ok to use const.
Still couple concerns:
I read in stackoverflow that const works differently in C vs C++, but what I understood is that it's more optimized in C++ and also should work fine too in C. Is that right ?
Does it affect the program speed or performance to use either define or const ?
david_2018: #define is used by the preprocessor to do what amounts to a text substitution, before invoking the compiler.
The const is processed by the compiler, so there will be type checking and possible generation of warnings or errors if applicable.
If you look at the amount of dynamic memory (RAM) used for each of your tests, that does not change because of the compiler optimizations hard coding the const values into the code, so there is no disadvantage to using const in terms of RAM usage.
You do need to be careful when choosing types, one of your test const values will not produce the expected output.
For a start; if I want to change things in my libraries.
For example; I want to change the GLCD defines,
from:
wolfrose:
I thought so, because with const I can control the size of the value, defines are 2 bytes.
No. #define has NO defined size, and uses NO RAM at all. What you DO with the #define value MAY cause some RAM to be used, but not by the #define itself. #define is NOTHING but a text substitution that occurs before the compiler is even run. It does nothing but a cut-and-paste of one sequence of characters in the source file for another.
RayLivingston:
No. #define has NO defined size, and uses NO RAM at all. What you DO with the #define value MAY cause some RAM to be used, but not by the #define itself. #define is NOTHING but a text substitution that occurs before the compiler is even run. It does nothing but a cut-and-paste of one sequence of characters in the source file for another.
OK, thank you very much for clearing this point. So it does not take any space in program but when used.
So it's same like declaring a variable, so declaring a variable doesn't take any space but using the variable use program/RAM space, am I right in this one ?
So, if there is no difference in declaring/using "define" vs "const var" ? is that right ? and which is recommended for const values like the ones in #10 ? and not macros, because macros vs functions is another story.
A #define consumes NO RAM. const variables consume NO RAM. The difference between the two is the const variable has a type, so the compiler can do type checking whenever the const variable is referenced. A #define has NO type. It is nothing more than a literal string, and that is used to replace another literal string in the source code. The effect is PRECISELY the same as if you manually did a global search and replace on the source code with your text editor, before compiling the code. That is exactly what the pre-processor does with all #defines.
I read somewhere that to guarantee a const to be a compile time constant like a #define that you should use: constexpr uint8_t CS_PIN = 10;
or better yet: static constexpr uint8_t CS_PIN = 10;
Apparently const can be subverted so it may not always be a compile time constant.
EDIT: I remember now. If you take the address of a constant then it will be placed in RAM you cannot take the address of a constexpr.
wolfrose:
wow that's interesting ! Thank you so much, I'm really enjoying this thread :)Well, if that would provide the same effect as #define, then I would keep the defines, it's easier to write I guess.