As they say...
To parse complicated types, you start at the variable, go left, and spiral outwards. If there aren't any arrays or functions to worry about (because these sit to the right of the variable name) this becomes a case of reading from right-to-left. So with char *const a; you have a, which is a const pointer (*) to a char. In other words you can change the char which a is pointing at, but you can't make a point at anything different. Conversely with const char* b; you have b, which is a pointer (*) to a char which is const. You can make b point at any char you like, but you cannot change the value of that char using *b = ...;. You can also of course have both flavours of const-ness at one time: const char *const c;.
( src )
There is a simple rule of thumb to memorize this. Just keep in your mind, how printf() and strcmp() are declared:
... int printf(const char *format, ...); ... int strcmp(const char *s1, const char *s2); ...
Here they talk about "constness" of data in strings, not about pointers. Const pointer is declared other way round: "char* const s".
Now what about reverse engineering? When you work on a code that Hex-Rays or Ghidra produced, it's very convenient to add const modifiers, to be sure sure, that a specific function argument is in fact "read-only" or "input". If you've mistaken, a C/C++ compiler will warn you about it during compilation time.
List of my other blog posts.
Yes, I know about these lousy Disqus ads. Please use adblocker. I would consider to subscribe to 'pro' version of Disqus if the signal/noise ratio in comments would be good enough.