Since my compiler gives different statistics for these two pieces of code, I am wondering what makes them different, if at all?
First one:
typedef const struct process_data
{
uint8_t *name;
void (*p_func)(void);
} process_data_t;
process_data_t processes = {15,16};
And the second one is:
typedef struct process_data
{
uint8_t *name;
void (*p_func)(void);
} process_data_t;
const process_data_t processes = {15,16};
Note that const
qualifier has moved from typedefing to the definition of the structure. For me there is no difference between the two excerpts, but the compiler/linker statistic shows that less flash memory (the platform is a microcontroller with constrained resources) is consumed when the second piece of code is used.
An expression is a mathematical phrase that contains numbers, variables, or both. Expressions never have an equal sign. Here are some examples of expressions. An equation is a mathematical sentence that says two expressions are equal.
An expression is a sentence fragment that stands for a single numerical value. On the contrary, an equation is a sentence showing equality between two expressions. The expression is simplified, through evaluation where we substitute values in place of variables. Conversely, an equation is solved.
Answer. lst * 3 will give [1, 3, 5, 1, 3, 5, 1, 3, 5] but the original lst will remains unchanged, it will be [1, 3, 5] only. lst *= 3 will also give [1, 3, 5, 1, 3, 5, 1, 3, 5] only but it will assign this result back to lst so lst will be changed to [1, 3, 5, 1, 3, 5, 1, 3, 5].
There is some amount of freedom that the compiler can take in interpreting these declarations, but, in general, here is the difference:
The typedef
"says": this is a type that is always const
, meaning there is no "legal" way to take away the const
-nes of any variable of this type. Whenever you pass data of this type or pointers to it, they will be const. Sure, casting "works", but only to another type, and may lead to Undefined Behavior.
The const
data "says": This data is const
, but, other data of this type may not be, so, at least some amount of "taking away const
-nes" is OK between variables and pointers of this type. Of course, if someone casts pointer to this data to non-const and it is indeed in read-only memory, we're in trouble.
So, the bottom line is the same, but there is a subtle difference. How the compiler interprets that is really up to the compiler. It may very well be that the typedef
is very rare (it is in my experience), so the compiler is optimised for the more common case.
There is a difference between data definitions declared const
, and regular const
ness, in that it becomes undefined behaviour (at least in C++) if you cast away the const
from an object that was defined with the qualifier.
Outside of language-lawyering, the rationale is obvious: we want these as part of the read-only image, while still permitting both people who know what they are doing to use const_cast
, because there are good reasons for that as well.
In C, we have pretty much the same motivation: put constants into read-only memory, but allow casts to work. When the qualifier is attached to the type, that is not a strong guarantee that the user intended the variable to go to read-only memory, so the compiler may err on the side of caution here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With