Author Topic: what the hell does "uint8_t const foo" do?  (Read 3953 times)

0 Members and 2 Guests are viewing this topic.

Offline DavidAlfaTopic starter

  • Super Contributor
  • ***
  • Posts: 5914
  • Country: es
what the hell does "uint8_t const foo" do?
« on: December 30, 2023, 05:11:08 pm »
I accepted a PR from someone quite some time ago, appart from strange bugs I had to fix and strange over-complicated programming syntax, all ram variables were declared this way.
It's not const var, but var const???
Code: [Select]
void foo(uint8_t a){
  uint8_t const b = a+1;
  do_something(b);
}

Was puzzling me out so I removed them all, but does it mean anything?
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Online tellurium

  • Regular Contributor
  • *
  • Posts: 232
  • Country: ua
Re: what the hell does "uint8_t const foo" do?
« Reply #1 on: December 30, 2023, 05:16:50 pm »
It declares a constant value, so if you attempt to change it in the function body, you'll get a compiler warning.
However, in that snippet, "b" gets passed to the function. Since arguments are passed by value, it renders "const" useless.
Open source embedded network library https://mongoose.ws
TCP/IP stack + TLS1.3 + HTTP/WebSocket/MQTT in a single file
 

Offline ledtester

  • Super Contributor
  • ***
  • Posts: 3039
  • Country: us
Re: what the hell does "uint8_t const foo" do?
« Reply #2 on: December 30, 2023, 05:18:07 pm »
On this page:

https://en.cppreference.com/w/cpp/language/cv

in the example at the bottom you will see this code:

Code: [Select]
#include <cstdlib>
 
int main()
{
    int n1 = 0;          // non-const object
    const int n2 = 0;    // const object
    int const n3 = 0;    // const object (same as n2)
    volatile int n4 = 0; // volatile object
...

So it appears that "const int" and "int const" are the same.

 

Online eutectique

  • Frequent Contributor
  • **
  • Posts: 393
  • Country: be
Re: what the hell does "uint8_t const foo" do?
« Reply #3 on: December 30, 2023, 05:21:09 pm »
It's not const var, but var const???

var const would look like

Code: [Select]
uint8_t b const = a+1;
 

Online hans

  • Super Contributor
  • ***
  • Posts: 1641
  • Country: nl
Re: what the hell does "uint8_t const foo" do?
« Reply #4 on: December 30, 2023, 05:36:31 pm »
Relevant read: https://stackoverflow.com/questions/162480/const-int-vs-int-const-as-function-parameters-in-c-and-c

The reading right-to-left trick sounds useful for this. Indeed, const char * and char const * are identical (coding style), whereas char * const is distinctly different, so there is some argument for putting const right behind whatever you're trying to fixate. In that view, char const * is less ambiguous.

I personally don't do it. Maybe its a minor inconsistency, but I also didn't knew this, so I might think about it.
 

Offline DavidAlfaTopic starter

  • Super Contributor
  • ***
  • Posts: 5914
  • Country: es
Re: what the hell does "uint8_t const foo" do?
« Reply #5 on: December 30, 2023, 06:15:52 pm »
Then it makes no sense when the function input is variable? :-//
And it was weird that "a"=non-const, "b"=const, but b=a caused no compiler warning.
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3240
  • Country: gb
Re: what the hell does "uint8_t const foo" do?
« Reply #6 on: December 30, 2023, 07:09:17 pm »
Then it makes no sense when the function input is variable? :-//
And it was weird that "a"=non-const, "b"=const, but b=a caused no compiler warning.

In the example code in your first post the const is pretty much redundant, but if there were any additional code in the function that uses b then it is useful if you don't want it to be changed.
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11655
  • Country: my
  • reassessing directives...
Re: what the hell does "uint8_t const foo" do?
« Reply #7 on: December 30, 2023, 07:11:03 pm »
Then it makes no sense when the function input is variable? :-//
However, in that snippet, "b" gets passed to the function. Since arguments are passed by value, it renders "const" useless.
no its not. you only cant modify b in function body. a copy of it (passed by value or assigned to something else), you can.

And it was weird that "a"=non-const, "b"=const, but b=a caused no compiler warning.
during first definition/declaration, its ok... much like const X = 77;

Was puzzling me out so I removed them all,
a good way if you dont have anything else to do ;D if its not broken why fix it?
« Last Edit: December 30, 2023, 07:14:35 pm by Mechatrommer »
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8180
  • Country: fi
Re: what the hell does "uint8_t const foo" do?
« Reply #8 on: December 30, 2023, 07:11:49 pm »
b does not change, that is told to the compiler and other human readers by the const qualifier. You definitely should be seeing compiler error, not a warning:

Code: [Select]
#include <stdio.h>

int main()
{
        int a = 1;
        const int b = a + 1;
        b = 2;
        printf("b = %d\n", b);
}

$ gcc tt.c
tt.c: In function ‘main’:
tt.c:7:4: error: assignment of read-only variable ‘b’
    7 |  b = 2;
      |    ^


Being const-correct is considered one of the most basic and most important quality requirements, although I admit being sloppy quite often. If you don't know what it is, don't touch it. It's there for a reason; don't make it worse.

For that example to be actually const-correct, the function itself should have its argument qualified const, too. Hopefully it is.
« Last Edit: December 30, 2023, 07:13:21 pm by Siwastaja »
 
The following users thanked this post: newbrain

Offline DavidAlfaTopic starter

  • Super Contributor
  • ***
  • Posts: 5914
  • Country: es
Re: what the hell does "uint8_t const foo" do?
« Reply #9 on: December 30, 2023, 07:20:35 pm »
For example:
Code: [Select]
static void writeFlash(uint32_t* src, uint32_t len, uint32_t dstAddr)
{
  uint32_t const numWordsToWrite = (len + sizeof(uint32_t) - 1u) / sizeof(uint32_t);

What would be the difference?
The compiler will know if the function arguments are constant or coming from volatile sources, and optimize accordingly, right?
"Forcing" it constant will cause warnings or errors, thus extra work, if the program changes in the future and takes the argument from elsewhere?

a good way if you dont have anything else to do ;D if its not broken why fix it?
Becase I like uniformity. 99% of the code without const, those with const. My eyes catched that every time!
« Last Edit: December 30, 2023, 07:22:44 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11655
  • Country: my
  • reassessing directives...
Re: what the hell does "uint8_t const foo" do?
« Reply #10 on: December 30, 2023, 07:34:23 pm »
For example:
Code: [Select]
static void writeFlash(uint32_t* src, uint32_t len, uint32_t dstAddr)
{
  uint32_t const numWordsToWrite = (len + sizeof(uint32_t) - 1u) / sizeof(uint32_t);

What would be the difference?
The compiler will know if the function arguments are constant or coming from volatile sources, and optimize accordingly, right?
"Forcing" it constant will cause warnings or errors, thus extra work, if the program changes in the future and takes the argument from elsewhere?
its the original programmer's intention he's trying to tell you (the maintainer) something, what was it? who knows? and you dont show the whole codes... so who knows?

a good way if you dont have anything else to do ;D if its not broken why fix it?
Becase I like uniformity. 99% of the code without const, those with const.
oh those were the days and spirit. nowadays i only do that on newly created program (i maintain my own code, even i always forgot what was my intention years ago)

My eyes catched that every time!
either you have naming convention such as const myvar_const or your program is simple enough to catch them... ymmv.
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14490
  • Country: fr
Re: what the hell does "uint8_t const foo" do?
« Reply #11 on: December 30, 2023, 08:44:00 pm »
- The order of the qualifiers does not matter here. 'const type' or 'type const' is the same. I admit I have rarely seen a code style with the qualifier(s) after the type rather than before, but it's a matter of code style, and no two people have exactly the same, so... (It's actually a good source of endless wars.)
- Yes as mentioned above, not to be confused with the distinction between a const pointer and a pointer to const, which is a different case. Not completely trivial to understand at first. But the const is either after or before the '*', so the syntax is different. Not your concern here anyway.
- 'const' may not look useful in the case your showed, but at least it conveys the intent of the programmer that the variable should not be modified after having been initialized (and yes, obviously you can initialize a const variable, otherwise how would you ever use them? But you can't modify them after that.) For instance, in the first piece of code you showed, it means that b should not change. As it is, it doesn't make a difference because it's used immediately in a call to a function, and nothing else, but if there is any code added in between, or after the call, in future modifications, then it prevents you from modifying b for any reason you may have. So yes, it can be useful.

Remember that code is written to be understood and maintained, not just to compile.

 

Online peter-h

  • Super Contributor
  • ***
  • Posts: 3701
  • Country: gb
  • Doing electronics since the 1960s...
Re: what the hell does "uint8_t const foo" do?
« Reply #12 on: December 30, 2023, 09:48:39 pm »
Surely

Quote
const int b = a + 1;

compiles only because a=1 beforehand, so the compiler can see b cannot be anything other than 2.

Otherwise b cannot be "const".

Having said that, I don't write code which I don't understand so I don't use "const". If something is really fixed I use #define :)

« Last Edit: December 30, 2023, 09:50:26 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline abeyer

  • Frequent Contributor
  • **
  • Posts: 292
  • Country: us
Re: what the hell does "uint8_t const foo" do?
« Reply #13 on: December 30, 2023, 11:35:49 pm »
Surely

Quote
const int b = a + 1;

compiles only because a=1 beforehand, so the compiler can see b cannot be anything other than 2.

Otherwise b cannot be "const".


No, const in C/C++ doesn't mean compile-time constant... it's perfectly valid to have a const variable with a value determined at runtime.
 
The following users thanked this post: Siwastaja

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 3727
  • Country: us
Re: what the hell does "uint8_t const foo" do?
« Reply #14 on: December 31, 2023, 02:48:17 am »
For example:
Code: [Select]
static void writeFlash(uint32_t* src, uint32_t len, uint32_t dstAddr)
{
  uint32_t const numWordsToWrite = (len + sizeof(uint32_t) - 1u) / sizeof(uint32_t);

What would be the difference?
The compiler will know if the function arguments are constant or coming from volatile sources, and optimize accordingly, right?

It has almost nothing to do with optimization and nothing to do with volatile other than occupying the same place in the grammar for mostly silly reasons.

Quote
"Forcing" it constant will cause warnings or errors, thus extra work, if the program changes in the future and takes the argument from elsewhere?

It will only cause errors if you try to modify a variable you declared as not to be modified.  In that case you *want* the error.

That said, I don't regularly mark local variables as const even when I could, at least not in C.  It's much more useful (and hard to get right) with pointers, where it declares that the function accepting a pointer argument won't be modifying the data pointed to.
 

Offline DavidAlfaTopic starter

  • Super Contributor
  • ***
  • Posts: 5914
  • Country: es
Re: what the hell does "uint8_t const foo" do?
« Reply #15 on: December 31, 2023, 05:12:39 am »
Yeah I perfectly know the difference in pointers, it's was this specific case causing some  ???.
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8180
  • Country: fi
Re: what the hell does "uint8_t const foo" do?
« Reply #16 on: December 31, 2023, 06:57:40 am »
For example:
Code: [Select]
static void writeFlash(uint32_t* src, uint32_t len, uint32_t dstAddr)
{
  uint32_t const numWordsToWrite = (len + sizeof(uint32_t) - 1u) / sizeof(uint32_t);

"Forcing" it constant will cause warnings or errors, thus extra work, if the program changes in the future and takes the argument from elsewhere?

This is the whole point, preventing accidental or poorly thought out modifications. Yes, if you want to modify the code so that numWordsToWrite changes on the fly, after the initial calculation, then the original programmer thought "hmm, that would require quite some care or large modifications". In that case, you obviously remove the const qualifier, and that will be the smallest part of the change. As the code stands now, the const alone tells the reader that this won't change, making the code quicker to understand.

Inside a code block like this, it is true const is not needed for optimization; any half-decent compiler can deduce the value does not change anyway. In interfaces (functions within different modules linked without LTO), e.g. with pointers, using the const qualifier is even more important, and also for performance. See also: restrict qualifier.
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8180
  • Country: fi
Re: what the hell does "uint8_t const foo" do?
« Reply #17 on: December 31, 2023, 07:01:26 am »
Becase I like uniformity. 99% of the code without const, those with const. My eyes catched that every time!

This is way too common, in my code too I'm sloppy and lazy and don't always write const-correct code. Better habit than removing const qualifiers would be to start adding them. But if the code base is 99% const-incorrect and 1% const-correct, that would be a daunting task. Still, don't remove it; start getting used to better programming practices instead! C is a surprisingly modern high-level programming language when used to its full capability; yet people, me included, write horrible hacks with it.
 
The following users thanked this post: newbrain, eutectique

Offline DavidAlfaTopic starter

  • Super Contributor
  • ***
  • Posts: 5914
  • Country: es
Re: what the hell does "uint8_t const foo" do?
« Reply #18 on: December 31, 2023, 01:33:09 pm »
So you say that it's a way of ensuring the value is always dependant on constant sources:
Code: [Select]
int a=1;                         // a is assigned at compile time, thus constant
int const c = a + 2;         // This will compile fine

Code: [Select]
int b= readUART();         // b is volatile here
int const c = b + 2;         // This will cause compile error

Code: [Select]
int a= i;                        // a is constant
int b= readUART();         // b is volatile
int const j = b + 2;         // Oops! I meant a, not b. Thankfully I will get a compiler error showing this fuck-up.
« Last Edit: December 31, 2023, 01:36:48 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11655
  • Country: my
  • reassessing directives...
Re: what the hell does "uint8_t const foo" do?
« Reply #19 on: December 31, 2023, 02:49:58 pm »
no. its a way to prohibit yourself (or others) to do the bolded line...
Quote
int a=1;
int const c = a + 2;
c = a;

or
Quote
int b= readUART();         // b is volatile here
int const j = b + 2;
j = whatever;

why is it so hard to understand?
https://www.w3schools.com/cpp/cpp_variables_constants.asp
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Online peter-h

  • Super Contributor
  • ***
  • Posts: 3701
  • Country: gb
  • Doing electronics since the 1960s...
Re: what the hell does "uint8_t const foo" do?
« Reply #20 on: December 31, 2023, 03:02:14 pm »
Reading that link above, what is the difference (in terms of read-only protection) between

const uint32_t fred = 2;

and

#define fred 2

The examples they give

const int minutesPerHour = 60;
const float PI = 3.14;

are perfectly suited to #define

I think, and e.g. here https://www.geeksforgeeks.org/const-qualifier-in-c/ the intention is that after the initial assignment the value is read-only. It obviously cannot be read-only the whole time otherwise you could not assign the value in the first place :)

Obviously there are cases where you want a "read only variable" e.g. when creating an array of bytes which you will later be indexing into, each with its initial value, but for lone variables??

But would this R/O protection be implemented by the compiler if such a const array was later modified via a runtime computed index, or worse still a pointer? I've seen compiler behaviour where it replaced an array to array data copy loop with a memcpy and for that it must have been sure it had correctly "simulated" the index ranges, but what if you took this a step further and set a pointer p to the array base and then did a calculation on p?
« Last Edit: December 31, 2023, 03:54:47 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline gf

  • Super Contributor
  • ***
  • Posts: 1187
  • Country: de
Re: what the hell does "uint8_t const foo" do?
« Reply #21 on: December 31, 2023, 04:41:11 pm »
Reading that link above, what is the difference (in terms of read-only protection) between

const uint32_t fred = 2;

and

#define fred 2

The examples they give

const int minutesPerHour = 60;
const float PI = 3.14;

are perfectly suited to #define

It may be a personal preference of mine, but what I don't like about macros is that they "pollute" the entire program, so that you cannot re-use the same identifier in a different scope for a different purpose.

For instance

Code: [Select]
#define fred 2

int f()
{
  char* fred = "fred";    // <-- syntax error
  // ... whatever
}

int g()
{
  return fred;    // returns 2
}

won't compile, while

Code: [Select]
static const int fred = 2;

int f()
{
  char* fred = "fred";    // OK
  // ... whatever
}

int g()
{
  return fred;    // returns 2
}

does compile.

Quote
I think [...] the intention is that after the initial assignment the value is read-only. It obviously cannot be read-only the whole time otherwise you could not assign the value in the first place :)

Exactly that. And for automatic variables, the initial value does not need to be a compile-time constant. Static and global variables, OTOH, can only be initialized with compile-time constant expressions in general.

[ C23 also added a "constexpr" specifier for compile time constants. This specifier ensures that the initializer is a compile-time constant expression. See https://en.cppreference.com/w/c/language/constexpr ]
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8180
  • Country: fi
Re: what the hell does "uint8_t const foo" do?
« Reply #22 on: December 31, 2023, 05:13:30 pm »
So you say that it's a way of ensuring the value is always dependant on constant sources:

No, nothing like that. You are overthinking the capabilities of const qualifier. It just means you can't change that variable after initialization, nothing else. Initialization value can be anything, including something only known at runtime. Really, read all the replies carefully - and some book or the standard.
 
The following users thanked this post: newbrain, dare

Offline gf

  • Super Contributor
  • ***
  • Posts: 1187
  • Country: de
Re: what the hell does "uint8_t const foo" do?
« Reply #23 on: December 31, 2023, 05:28:11 pm »
But would this R/O protection be implemented by the compiler if such a const array was later modified via a runtime computed index, or worse still a pointer? I've seen compiler behaviour where it replaced an array to array data copy loop with a memcpy and for that it must have been sure it had correctly "simulated" the index ranges, but what if you took this a step further and set a pointer p to the array base and then did a calculation on p?

Unfortunately, C does allow the assignment of  const type*  to  type* pointers. Even without cast.
Gcc only spits out a warning. Example: https://godbolt.org/z/jfE1jdaEP
So you can indirectly modify const objects.

OTOH, C++ does not allow this conversion, neither implicitly, nor with static_cast(), nor with reinterpret_cast().
You explicitly need to use a const_cast(), or a traditional C-style cast (which is rather taboo in C++ anyway) to do that, so it can hardly happen by accident.
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8180
  • Country: fi
Re: what the hell does "uint8_t const foo" do?
« Reply #24 on: December 31, 2023, 05:54:40 pm »
Gcc only spits out a warning. Example: https://godbolt.org/z/jfE1jdaEP
So you can indirectly modify const objects.

The good news is, it does spit out a warning. Better get used to the fact that C becomes a much better language with -Wall -Werror
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf