So, in this guide I read that saying
char * terry;
was different from saying
char* terry; //or
char *terry; // FYI: I understand what these two do.
as stated by
"I want to emphasize that the asterisk sign (*) that we use when
declaring a pointer only means that it is a pointer (it is part of its
type compound specifier), and should not be confused with the
dereference operator that we have seen a bit earlier, but which is
also written with an asterisk (*). They are simply two different
things represented with the same sign."
However I do not understand why. Perhaps I took the quote the wrong way, now that I have read it once again, but I am still confused. Can anyone tell me if this is wrong or right and why?
Thank you.
No, all three are exactly the same as far as the parser is concerned. People certainly have their reasons for using each style, but there's not really a "right" way. As an editorial note, I prefer:
char *terry;
What the author of your link is describing is that the * in the declaration is somehow different from the unary * operator used to dereference a pointer:
char *terry = "abcdefg"; // declaration & initialization
*terry = 'x'; // dereference
This potential funny business is actually one of the reasons I prefer the notation I mentioned above - it makes both cases look the same, so there's no room for confusion.
I think all three are the same
Once you have declared a pointer e.g.
int *x;
and later on you want to dereference it you'd use
*x
Textbooks often recommend writing char *terry to remind you that in the statement char *terry, jerry terry is a pointer but jerry is not. Avoids a noobie mistake.
Others write char* terry because they read it as "char-pointer terry." These people probably never declare pointers and non-pointers, or even just two pointers, on the same line. Which is not a bad rule to use.
Otherwise, whitespace almost never matters in C++. Except inside identifiers (variable names, function names) and... can't think of anything else.
I prefer
char *terry;
Just because then if you do something like
char *terry, *jerry, larry;
It's obvious you forgot a pointer.
You may have misread.
char * terry;
char* terry;
char *terry;
Are all the same way to declare a char pointer, named terry.
As for the "right" way, that depends on your coding standard. I personally use char* terry
he is trying to differentiate between the definition char *terry and its usage after the definition e.g. perry = *terry; where perry takes the value of terry rather than the address. As far as compilers are concerned, and others have noted in there answers all three definitions are same. I prefer char *terry, where asterisk(*) hugs the variable.
char* terry; //or
char *terry;
Simply means you are declaring a pointer of char type.
Now terry hold the address location of a character variable, which you have might asked terry to point.
If you print terry, it will print the memory location.
If you dereference terry ( *terry) you will get the character, it is pointing to.
That is what that write up you are mentioning is telling.
Related
According to the c++ grammar, const int* const p means that what p points to and it' value can't be rewritten.But today I found that if I code like this:
void f(const int* const p)
{
char* ch = (char*) p;
int* q = (int*) ch;
(*q) = 3; //I can modify the integer that p points to
}
In this condition,the keyword "const" will lose it's effect.Is there any significance to use "const"?
You are casting away the constness here:
char* ch = (char*) p;
Effectively, you are saying "I know what I am doing, forget you are const, I accept the consequences." C++ allows you to do stuff like this because sometimes it can be useful/necessary. But it is fraught with danger.
Note that if the argument passed to the function were really const, then your code would result in undefined behaviour (UB). And you have no way of knowing from inside the function.
Note also that in C++ it is preferable to make your intent clear,
int* pi = const_cast<int*>(p);
This makes it clear that your intention is to cast away the const. It is also easier to search for. The same caveats about danger and UB apply.
Your example will crash the app if const int* const p points to a compile time constant, when casting away constancy you need to be sure what you are doing.
C++ is a language for adults, extra power will never be sacrificed for ephemeral safety, it is the code author's choice whether to stay in a safe zone or to use cast operators and move one step closer to C/asm.
C/C++ will let you do many things that allow you to 'hurt' yourself. Here, casting away the const of p is "legal" because the compiler assumes you know what you are doing. Whether this is good coding style or not is another matter.
When you do something like this, you assume responsibility for any side effects and issues it could create. Here, if the memory pointed to in the parameter is static memory, the program will likely crash.
In short, just because you can do something doesn't mean it is a good idea.
The const keyword is a way to use the compiler to catch programming mistakes, nothing more. It makes no claims about the mutability of memory at runtime, only that the compiler should shout at you if you directly modify the value (without using C-style casts).
A C-style cast is pretty much a marker saying 'I know what I'm doing here'. Which in most instances is false.
Here you change the type of the pointer. Using such a cast (C-type) cast you can change it to any possible pointer with no problem.
The same way you can use c++ cast: const_cast<...>(...):
int* p_non_const = const_cast<int*>(p);
In this case (I hope) you see immediately what is happening - you simply rid of the constness.
Note that in your program you also don't need temprorary variable ch. You can do it directly:
int* q = (int*) p;
In principle you should not use such a cast, because correctly designed and written program doesn't need it. Usually the const_cast is used for quick and temporary changes in the program (to check something) or to use a function from some unproperly designed library.
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.
Code:
void *buff;
char *r_buff = (char *)buff;
I can't understand the type casting of buff. Please help.
Thank you.
buff is a pointer to some memory, where the type of its content is unspecified (hence the void).
The second line tells that r_buff shall point to the same memory location, and the contents shall be interpreted as char(s).
buff is typed as a void pointer, which means it points to memory without declaring anything about the contents.
When you cast to char *, you declare that you're interpreting the pointer as being a char pointer.
In well written C++, you should not use C-style casts. So your cast should look like this:
void *buff;
char *r_buff = static_cast<char *>(buff);
See here for an explanation of what the C++ casting operators do.
By its name, buff is likely to be a memory buffer in which to write data, possibly binary data.
There are reasons why one might want to cast it to char *, potentially to use pointer arithmetic on it as one is writing because you cannot do that with a void*.
For example if you are supplied also a size (likely) and your API requires not pointer and size but 2 pointers (begin and end) you will need pointer arithmetic to determine where the end is.
The code could well be C in which case the cast is correct. If the code is C++ though a static_cast is preferable although the C cast is not incorrect in this instance. The reason a static_cast is generally preferred is that the compiler will catch more occasions when you cast incorrectly that way, and it is also more easily greppable. However casting in general breaks type-safety rules and therefore is preferably avoided much of the time. (Not that it is never correct, as it may be here).
Is there a "good" way to write "pointer to something" in C/C++ ?
I use to write void foo( char *str ); But sometimes I find it quite illogical because the type of str is "pointer to char", then it should more logical to attach the * to the type name.
Is there a rule to write pointers ?
char*str;
char* str;
char *str;
char * str;
There is no strict rule, but bear in mind that the * attaches to the variable, so:
char *str1, *str2; // str1 and str2 are pointers
char* str1, str2; // str1 is a pointer, str2 is a char
Some people like to do char * str1 as well, but it's up to you or your company's coding standard.
The common C convention is to write T *p, whereas the common C++ convention is to write T* p. Both parse as T (*p); the * is part of the declarator, not the type specifier. It's purely an accident of pointer declaration syntax that you can write it either way.
C (and by extension, C++) declaration syntax is expression-centric; IOW, the form of a declaration should match the form of an expression of the same type in the code.
For example, suppose we had a pointer to int, and we wanted to access that integer value. To do so, we dereference the pointer with the * indirection operator, like so:
x = *p;
The type of the expression *p is int; thus, it follows that the declaration of p should be
int *p
The int-ness of p is provided by the type specifier int, but the pointer-ness of p is provided by the declarator *p.
As a slightly more complicated example, suppose we had a pointer to an array of float, and wanted to access the floating point value at the i'th element of the array through the pointer. We dereference the array pointer and subscript the result:
f = (*ap)[i];
The type of the expression (*ap)[i] is float, so it follows that the declaration of the array pointer is
float (*ap)[N];
The float-ness of ap is provided by the type specifier float, but the pointer-ness and array-ness are provided by the declarator (*ap)[N]. Note that in this case the * must explicitly be bound to the identifer; [] has a higher precedence than unary * in both expression and declaration syntax, so float* ap[N] would be parsed as float *(ap[N]), or "array of pointers to float", rather than "pointer to array of float". I suppose you could write that as
float(* ap)[N];
but I'm not sure what the point would be; it doesn't make the type of ap any clearer.
Even better, how about a pointer to a function that returns a pointer to an array of pointer to int:
int *(*(*f)())[N];
Again, at least two of the * operators must explicitly be bound in the declarator; binding the last * to the type specifier, as in
int* (*(*f)())[N];
just indicates confused thinking IMO.
Even though I use it in my own C++ code, and even though I understand why it became popular, the problem I have with the reasoning behind the T* p convention is that it just doesn't apply outside of the simplest of pointer declarations, and it reinforces a simplistic-to-the-point-of-being-wrong view of C and C++ declaration syntax. Yes, the type of p is "pointer to T", but that doesn't change the fact that as far as the language grammar is concerned * binds to the declarator, not the type specifier.
For another case, if the type of a is "N-element array of T", we don't write
T[N] a;
Obviously, the grammar doesn't allow it. Again, the argument just doesn't apply in this case.
EDIT
As Steve points out in the comments, you can use typedefs to hide some of the complexity. For example, you could rewrite
int *(*(*f)())[N];
as something like
typedef int *iptrarr[N]; // iptrarr is an array of pointer to int
typedef iptrarr *arrptrfunc(); // arrptrfunc is a function returning
// a pointer to iptrarr
arrptrfunc *f; // f is a pointer to arrptrfunc
Now you can cleanly apply the T* p convention, declaring f as arrptrfunc* f. I personally am not fond of doing things this way, since it's not necessarily clear from the typedef how f is supposed to be used in an expression, or how to use an object of type arrptrfunc. The non-typedef'd version may be ugly and difficult to read, but at least it tells you everything you need to know up front; you don't have to go digging through all the typedefs.
The "good way" depends on
internal coding standards in your project
your personal preferences
(probably) in that order.
There is no right or wrong in this. The important thing is to pick one coding standard and stick to it.
That being said, I personally believe that the * belongs with the type and not the variable name, as the type is "pointer to char". The variable name is not a pointer.
I think this is going to be heavily influenced by the general pattern in how one declares the variables.
For example, I have a tendency to declare only one variable per line. This way, I can add a comment reminding me how the variable is to be used.
However, there are times, when it is practical to declare several variables of the same type on one line. Under such circumstances, my personal coding rule is to never, NEVER, EVER declare pointers on the same line as non-pointers. I find that mixing them can be a source of errors, so I try to make it easier to see "wrongness" by avoiding mixing.
As long as I follow the first guideline, I find that it does not matter overly much how I declare the pointers so long as I am consistent.
However, if I use the second guideline and declare several pointers on the same line, I find the following style to be most beneficial and clear (of course others may disagree) ...
char *ptr1, *ptr2, *ptr3;
By having no space between the * and the pointer name, it becomes easier to spot whether I have violated the second guideline.
Now, if I wanted to be consistent between my two personal style guidelines, when declaring only one pointer on a line, I would use ...
char *ptr;
Anyway, that's my rationale for part of why I do what I do. Hope this helps.
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.