c++ Final constant strings - c++

In Java, we can specify a string as final to declare 'constants'. For example
static final String myConst = "Hello";
Is the correct way to do this in c++ like this?
const char * const myConst = "Hello";
I've always seen people do this:
const char * myConst = "Hello";
But, actually, you can change what that pointer points to. So, why do people not declare the pointer as constant as well? What is the correct way to do it?

const std::string myConst("Hello");

Yes, const char* const is the correct way to declare a C-style string which you will not change.
Or better:
#include <string>
const std::string myConst = "Hello";

const char * myConst = "Hello";
This means the object pointed at cannot change.
char * const myConst = "Hello";
This means the location pointed at by the pointer cannot change, but the object's value can.
const char * const myConst = "Hello";
This means neither may change. In my experience no one remembers this, but it's always available on the net!
Typical, three people answer in the time I write mine!

I don't exactly understand your question. To more or less mimic the final Java keyword, it would be either
const char * const myConst = "Hello";
(if the pointer is not going to change), and/or:
const char * myConst = "Hello";
if the pointer may change afterwards. Finally, note that with the first version, you cannot actually change the pointer itself, because it is constant.

With Diego's edit, yes, that the right way to write it. People typically don't declare the variable const because they don't care whether it will be modified, or, rather, trust that it won't be modified (since they know they don't modify it).
They declare the pointed-to const because a string literal really has const characters, so you really must assign it to a variable that has char const * values.

Technically,
char * const myConst = "Hello";
is the most correct answer, as reassigning the pointer would leave you with a string which probably could not be recovered.
Some implementations allow you to change the characters in "Hello" (even if it's a bad idea), so the first const in
char const * const myConst = "Hello";
Is a great idea. Personally as
char const * myConst = ...;
and
const char * myCount = ...;
are equivalent, I tend to enforce a style guideline that the const always follows the item it modifies. It sometimes reduces misconceptions in the long run.
That said, most people don't know how to use const correctly in C++, so it's either used poorly or not at all. That's because they just use C++ as an improved C compiler.

But, actually, you can change what
that pointer points to. So, why do
people not declare the pointer as
constant as well? What is the correct
way to do it?
Because it's rarely useful, more often than not you would want to have the values on the stack (pointers included) to be non-const. Get Sutter & Alexandrescu "Coding Standards" book, it explains this point.

The real point is that programmers are compeled to declare some pointers at least as const char * to store char arrays between double quotes. Nothing force them (no compiler warning or error) to also make the pointer constant... as people are lazy you can draw your own conclusion. They are probably not even really trying to define a constant, they just want to shut off compiler errors (well, warning in this case).
Keeping that in mind, I would probably go for a different solution anyway:
const char myConst[] = "Hello";
The difference here is that this way I won't decay the original byte array used as string to a pointer, I will still have a byte array that can be used exactly as the original literal.
With it I can do things like sizeof(myConst) and get the same result as with sizeof("Hello"). If I change string to a pointer, sizeof would return the size of a pointer, not the size of the string...
... and obviously when doing things this way changing the pointer becomes meaningless, as there is no pointer to change anymore.

Related

Convert const char* into a char*

I'm always wondering about the complaint of the compiler when I declare and define a char*-variable.
char* myChar = "Char";
The compiler will complain that it cannot convert const char* to char*. It need an explicit conversion like
char* myChar = (char*)"Char";
My first question is if this is the correct way to initialize a char* with a const char*. And my second question is, why the compiler need this explicit conversion. I think there is no great difference between const char* and char* except the const.
On a technical level, there is a great difference between const MyType* and MyType* and it is easier to see in your example char* myChar = "Char"; in that the litteral string can be part of memory that may not be changed, but by assigning that to a non-const pointer, you say that you may well planning to change some characters anyway. That behavior is undefined. It may work and it may make your program stop unexpectedly and you can't even rule out any other behavior.
By casting (prefer const_cast in C++), you are saying to the compiler that you know what you're doing and you know better. The normal solution is const char* myChar = "Char"; or even const char* const myChar = "Char"; if you're not planning to point to other char arrays.
In C++, I find it even clearer working with std::string if you want to work with strings.
To the advanced programmer, there is definitely a great difference between const and non-const, in terms of integrity, security, and performance.
We basically use const when we want to emphasize that a particular object/function/variable isn't allowed to be changed by the user.
check const correctness
The best-practice way to add/remove const/volatile modifiers is by using const_cast operator.
check The const_case operator

Passing char array to function

I have to call a method with the following signature:
int sendTo(const void* buffer, int length, const SocketAddress& address, int flags=0);
My first question is:
What does const void* buffer exactly mean? My intention is: it means that it is a constant (unmodifiable) pointer which can point to anything. ist this somehow right?
Second question:
The purpose of this method is, obviously, to send data over a socket.
The first parameter is the data, the second is the length of that data.
If I want to pass the string "hello" as the first parameter, how would I do this?
My idea:
char hello_str[1024] = "hello"
socket.sendTo(hello_str, sizeof(hello_str),.....);
would this work? But this way I have a way too big char array.
How can I create the array with the right size?
Recall that const protect its left side unless there's nothing to it's left, then it protects its right side. Applying this to your code we'll get that const is protecting void* buffer. That means that the value it points to cannot be modified:
The first is a pointer to a const variable - The pointer can be changed.
The second is a const pointer to a variable - The value can be changed.
This will work, you can easily try it.
And as others already answered, creating it with the right size is done simply by:
char hello_str[] = "hello";
it means that it is a constant (unmodifiable) pointer which can point to anything
No, that would be void *const. It's rather a pointer-to-anything, where the pointee (the "anything" itself) can't be modified.
would this work?
yes, apart from the missing semi-colon.
How can i create the array with the right size?
char hello_str[] = "hello";
or even
const char hello_str[] = "hello";
First question: H2C03 is right, you should make the type be void * const to prevent the pointer from being modified.
Second question: You have some options here, depending on exactly what you are doing. Here are two examples that would work:
char hello_str[] = "hello"
socket.sendTo(hello_str, sizeof(hello_str)-1,...);
socket.sendTo(hello_str, strlen(hello_str),...);
In the first call to sendto, we are calculating the size of the string at compile time. We subtract 1 in order to avoid sending the null termination character at the end of the string. In the second case, we are computing it at runtime by calling the standard strlen function which is available in C and C++.
What does const void* buffer exactly mean?
It's an untyped pointer (that's another way of saying that it can point to anything). The value it points to cannot be modified (that's not entirely correct, but at least that is what you should think when you see that). The pointer itself can change however:
const void * buffer = &a;
buffer = &b; // this is valid!
Besides that, your function call is completely correct.
You can do :
const char hello_str[] = "hello"; // Don't forget the const
socket.sendTo(hello_str, sizeof(hello_str)-1,.....);
// or socket.sendTo(hello_str, strlen(hello_str),.....);
To answer to your questions :
What does const void* buffer exactly mean? My intention is: it means that it is a constant (unmodifiable) pointer which can point to anything. ist this somehow right?
No, That would be void* const. const void* means that it is the pointee that cannot be modified.
You may read this.

When to use const char * and when to use const char []

I know they are different, I know how they are different and I read all questions I could find regarding char* vs char[]
But all those answers never tell when they should be used.
So my question is:
When do you use
const char *text = "text";
and when do you use
const char text[] = "text";
Is there any guideline or rule?
As an example, which one is better:
void withPointer()
{
const char *sz = "hello";
std::cout << sz << std::endl;
}
void withArray()
{
const char sz[] = "hello";
std::cout << sz << std::endl;
}
(I know std::string is also an option but I specifically want to know about char pointer/array)
Both are distinctly different, For a start:
The First creates a pointer.
The second creates an array.
Read on for more detailed explanation:
The Array version:
char text[] = "text";
Creates an array that is large enough to hold the string literal "text", including its NULL terminator. The array text is initialized with the string literal "text".The array can be modified at a later time. Also, the array's size is known even at compile time, so sizeof operator can be used to determine its size.
The pointer version:
char *text = "text";
Creates a pointer to point to a string literal "text". This is faster than the array version, but string pointed by the pointer should not be changed, because it is located in an read only implementation defined memory. Modifying such an string literal results in Undefined Behavior.
In fact C++03 deprecates use of string literal without the const keyword. So the declaration should be:
const char*text = "text";
Also,you need to use the strlen() function, and not sizeof to find size of the string since the sizeof operator will just give you the size of the pointer variable.
Which version is better?
Depends on the Usage.
If you do not need to make any changes to the string, use the pointer version.
If you intend to change the data, use the array version.
EDIT: It was just brought to my notice(in comments) that the OP seeks difference between:
const char text[] and const char* text
Well the above differing points still apply except the one regarding modifying the string literal. With the const qualifier the array test is now an array containing elements of the type const char which implies they cannot be modified.
Given that, I would choose the array version over the pointer version because the pointer can be(by mistake)easily reseated to another pointer and the string could be modified through that another pointer resulting in an UB.
Probably the biggest difference is that you cannot use the sizeof operator with the pointer to get the size of the buffer begin pointed to, where-as with the const char[] version you can use sizeof on the array variable to get the memory footprint size of the array in bytes. So it really depends on what you're wanting to-do with the pointer or buffer, and how you want to use it.
For instance, doing:
void withPointer()
{
const char *sz = "hello";
std::cout << sizeof(sz) << std::endl;
}
void withArray()
{
const char sz[] = "hello";
std::cout << sizeof(sz) << std::endl;
}
will give you very different answers.
In general to answer these types of questions, use the one that's most explicit.
In this case, const char[] wins because it contains more detailed information about the data within -- namely, the size of the buffer.
Just a note:
I'd make it static const char sz[] = "hello";. Declaring as such has the nice advantage of making changes to that constant string crash the program by writing to read-only memory. Without static, casting away constness and then changing the content may go unnoticed.
Also, the static lets the array simply lie in the constant data section instead of being created on the stack and copied from the constant data section each time the function is called.
If you use an array, then the data is initialized at runtime. If you use the pointer, the run-time overhead is (probably) less because only the pointer needs to be initialized. (If the data is smaller than the size of a pointer, then the run-time initialization of the data is less than the initialization of the pointer.) So, if you have enough data that it matters and you care about the run-time cost of the initialization, you should use a pointer. You should almost never care about those details.
I was helped a lot by Ulrich Drepper's blog-entries a couple of years ago:
so close but no cigar and more array fun
The gist of the blog is that const char[] should be preferred but only as global or static variable.
Using a pointer const char* has as disadvantages:
An additional variable
pointer is writable
an extra indirection
accessing the string through the pointer require 2 memory-loads
Just to mention one minor point that the expression:
const char chararr[4] = {'t', 'e', 'x', 't'};
Is another way to initialize the array with exactly 4 char.

Does the position of the * or & matters? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
In C, why is the asterisk before the variable name, rather than after the type?
What's your preferred pointer declaration style, and why?
In C++, i see pointers put in different ways. for example,
char* ptr
char * ptr
char *ptr
Are the 3 examples above identical? (same goes with the &)
Doesn't matter. (Eg. they are the same.) You could even write char*ptr; without any whitespace.
Beware though with multiple declarations on one line: char* ptr, noptr;. Here, the third syntax comes in clearer: char *ptr, noptr;.
My rule to avoid that confusion: Only one variable per line. Another way to do it right without the possibility to miss a *: typedef the pointer, eg:
typedef char* CharPtr;
CharPtr ptr1, ptr2; // now both are pointer
Though then you need to be aware of other things, like constness, so I stick to my rule mentioned above:
typedef char* CharPtr;
const CharPtr p1; // const char* ?? or char* const ??
CharPtr const p2; // char* const ?? or const char* ??
// Eg.: Can't the pointer or the pointee be changed?
(And all of the above also applies to references &.)
C people tend to prefer char *p, whereas C++ people tend to prefer char* p (at least Bjarne does). The compiler could not care less about whitespace, you could just as well say char * p or char*p.
Many people say that char* p is dangerous because char* p, q is potentially confusing. That is correct in principle, but:
To increase readability, you should not declare multiple names in one declaration, anyway.
And more importantly, in C++, you should generally prefer RAII types over raw pointers.
C++ people emphasize the types, and C people emphasize the usage.
So you see char* x in C++, it is because "the type of x is pointer-to-char". C++ has a strong type system on which the language rests. This is not the case in C.
In C, you declare variables according to what you want to do with them. When you see char *x in C, the thought process is "when you dereference x, you get a char". Another example:
char (*f)(int);
reads "when you dereference f and call it with a int, you get a char", ie. f is a pointer to a function which takes int and returns char.
They all work. char *ptr is often advocated because it makes it clearer what is happening in this case:
char *ptr, var;
This declares a char pointer and a char.
It does not matter. However, C++ people tend to prefer char* ptr, while C people prefer char *ptr. It's all a matter of personal preference.
However, note that char* ptr, noptr declares ptr as a pointer and noptr as a char value.
The potential whitespace surrounding the * and & modifiers in declaration have no effect on the compiled code.
C++ is a free-form language. So, space doesn't really count in this case and all mean the same.

New to C++. Question about constant pointers

I am trying to learn C++ via some web tutorials. I don't have a compiler available to me, otherwise I would try this out. I'm not sure what is meant by a const pointer. Does that just mean it always points to the same memory address? Why would you ever want to do that? Would the following code be legal?
...
int * const aPointer = new int;
... //do something with aPointer
delete aPointer;
... //do something else, including possibly more 'new' statements
aPointer = new int;
...
A simple way to remember how const works with pointers is to remember that it always applies to whatever is to the left of it, unless it's the left-most keyword, in which case it applies to the right.
Examples:
Pointer to a constant char:
The pointer can be changed to point to something else, but the char it initally points to cannot change value.
const char * p;
Constant pointer to a char:
The pointer cannot be changed to point to anything else, but the char it points to can change value.
char *const p;
Constant pointer to a constant char:
The pointer cannot be changed to point to anything else, and the char it points to cannot change value.
const char *const p;
Const pointer could mean a few different things. I recommend checking out the C++ FAQ Lite on the matter.
You can have:
const int* p;
int* const p;
const int* const p;
All three mean different things. Yes, it's kind of confusing.
In your case, you have the second, which means you have a constant pointer to a non-constant object. That is, you can change the value of the integer via the pointer, but you can't change what the pointer points to. So the code you posted would not be legal.
You can't learn to drive a car just by reading books.
Get yourself a C++ compiler if you want to learn C++. g++ is free of charge, as well as Visual Studio 2008 Express Edition.
As for your question, a const pointer is a zone of memory that is ready only. Example: A class may provide read-only access to an internal buffer.
Note that you also have the const pointer that is also const, aka
const char * const p
In that case, even the value of the pointer cannot be modified.
G'day,
To remember this easily you can use the trick that Scott Meyers describes in his excellent book "Effective C++" (sanitised Amazon link)
You draw a line through the declaration where the asterisk is located.
If the keyword const appears to the left of the line, then you can't change the value of the item that you're pointing to.
If the keyword const appears to the right of the line, then you can't change the pointer to point to another location.
If const appears on both sides, then you can't change the pointer and you can't change the value of what you're pointing to.
BTW That book is excellent, and while not for a beginner, is definitely a way of taking your C++ knowledge to the next level! Highly recommended.
HTH
cheers,
A const pointer means that you can change the value of the variable which is being pointed to, but you can't change where the pointer is pointed. I don't use them often myself, but a common application for const pointers is in defining specific memory segments that you need to address. See this question for more information.
As an aside, you should try to get a compiler on your computer if you can. I've shown myself many times that human brains are poor C++ compilers.
Your code is not legal. You can't assign to aPointer (except using copy-style initialisation, which in fact is not assignment even though it looks like it) if aPointer is declared const like that.
But usually when people say "a const pointer", they mean const int * aPointer, not int * const aPointer as you have in your code. The whole internet will explain the difference at the drop of a hat. As far as I know, the term "const pointer" isn't defined in the standard, so we're free to do this even though it's potentially confusing. "Pointer-to-const" would be an unambiguous description, and a pointer-to-const is much more commonly used than a pointer-which-is-itself-const.
A pointer-which-is-itself-const is used to refer to something, where you won't want the pointer to refer to a different thing at any point in its life. For instance, this is a pointer-which-is-itself-const, because "this object" remains the same object through the execution of a member function. The C++ language has opted not to let you decide part way through that you want to assign some other value to this, to make it refer to some other object. In C++ references often serve that purpose too, since they cannot be "re-seated" to change the referand.
In your code, the pointer cannot move, but the data pointed to can change.
It's legal up to the first delete. A subsequent new would not work because it's an assignment to a constant.
It's relatively unusual to see this, more common is to see where the data pointed to is unchangeable but the pointer can move.
int bar;
int baz;
const int * foo = &bar;
*foo = 4; // illegal
foo = &baz; // legal
having both pointer and value being const is common with strings
const wchar_t * const myString = L"String that will never change.";
Since you're new to C++, for the answer to this question and many other questions you may have or don't know you have, check out the C++ FAQ
I don't have a compiler available to me, otherwise I would try this out
Everyone has a C++ Compiler available to them: http://www.online-compiler.com
There are many others, but this seems to work...
As it has already been pointed out the perhaps most common const pointer is
const char* p;
The variable p can change, but the data p points to is unmodifable.
However, moving the const keyword to the left of the asterisk does not alter the meaning of the declaration:
char const* p;
I prefer the later since it becomes much easier to remember where to place the const keywords when declaring const pointers to const pointers:
char const* const* p;
Again, the variable p can change and the data pointed to is unmodifiable. Furthermore, the data is declared as const pointers meaning that it points to data that cannot be modified.
The more common notation for this type is
const char* const* p;
Placing the const keyword immediately to the left of the asterisk it modifies (or ampersand for reference) makes it easy to create complex types involving the const keyword. For example, a pointer to const pointers:
char const** p;
and a const pointer to pointers:
char* const* p;
Remember to "read" pointer declarations from the right to the left, and don't declare more than one pointer in each statement to avoid a lot of confusion.