int* p;
int& r;
int i;
double* p2;
double& r2;
double d;
p and p2 are pointers, r and r2 are references, but what are i and d? (No, I am not looking for the answer "an int and a double")
I am looking for a name to use for "normal" variables, setting them apart from pointers and references. I don't believe that such a name doesn't exist (after all, I can't be the first one who wants to distinguish them from pointers and references. I do have the feeling that it's something really easy and I'm just missing it here.
Who knows what to call "normal" variables?
Additional info
I am looking for a name that can refer to anything but references and pointers, so including classes. The whole same story could be held when the following was included as well:
MyClass* p3;
MyClass& r3;
MyClass c;
I am not looking for a way to refer to i, a way to refer to d and a way to c. I am looking for a way to refer to the group (of non-references, non-pointers) which i, d and c are part of.
If I understand what you are talking about, I would call it a value type.
Pointers and references are variables as well. I think it is sufficient to say that i is a variable of type int and p is a variable of type pointer to int. If they are members of a class i is a member variable of type int would be the most precise description.
Edit: There is no definite answer to your question. int would be a fundamental type in standard terminology. Other types as classes, unions and pointers are called compound types. This just isn't helpful in your case as you would refer to
A* a;
int* b;
A c;
as only consisting of compound types. But you want to emphasize that you use pointers. Just say it.
If you want the official terminology, then the C++ standard defines:
fundamental types, built-in value types such as int and double, and
compound types, including pointers and references, and also arrays, functions, classes, unions and enumerations.
It also uses the terms "object types", "reference types" and "function types", but it seems a bit vague to me about whether a pointer is an "object type" or a "reference type".
If you want to include fundamental types and classes, I would use the term "object type", and leave it to pedants to quibble about whether that should include pointers.
Value types (value variables) was my first thought, but it seems to make some people uncomfortable, so nonreferential types (nonreferential variables) works just as well: pointers and references are both "referential types" in the sense that they refer to another location, while ordinary value types do not.
They are just variables. Not pointers and not references, variables.
I think you want to use "non-pointer and non-reference type". There is no name especially designed for your purpose, i think.
A name which allows me to say, I am using pointers all over the place, but there in many cases there is no reason to do so, so I should change them to s wherever possible.
It sounds to me you look rather for "pass by copy" or "copy" vs "pass by reference" or "reference". The fact that you can pass a pointer by value makes it impossible to use an absolute term, but makes it necessary to use a term tied to the usecase:
int **p;
Is this a variable used to change a pointer of type int* (then it would be "pass by reference" in the sense you aim to modify the referent. To clarify that a pointer is used, you may wish to use the term "pass by pointer" too), or is this variable just used to hold a value of type int** (then it would be "pass by value" in the sense that you copy such a value)?
Values, or variables.
I typically call those "plain ol' data" (POD) variables, after the convention of referring to a struct as "POD" if it contains only data members (no functions). That's not an official convention, but it gets the point across (for simple types like int and float, it doesn't apply for classes).
I have also heard these types of variables called "concrete" variables. I think the distinction that was trying to be made is that these variables are something in and of themselves, whereas pointers and references simply tell you about some other piece of data somewhere else.
More than anything else, I hear these "loose" variables (that is, not a member of another object) referred to simply by their type (integer, floating-point number, class, etc).
i and d are consistently called objects in the C++ standard. But, then again, so are p, p2, and objects of class type such as the "c" of MyClass c;.
Personally I like calling i, d, and p objects, though it might be a little bit confusing to programmers of other languages such as Java, where they would be known as primitive variables with the term objects reserved for instances of classes.
EDIT: Instead of
I am using pointers all over the place, but there are many cases where there is no reason to do so, so I should change them to <normal variable>s wherever possible.
I would say: "I am using pointers all over the place, but there are many cases where there is no reason to do so, so I should remove the levels of indirection wherever possible."
I think we should call them OBJECTs. I think it's no need to be that strict.
Consider:
typedef int *, pint;
pint foo;
What do you think foo is?
Related
From what I can tell, references can be used wherever the original type can (I'm not implying the reverse is true), the only difference is their mutation semantics (when the variables are used as lvalues).
Wouldn't they then qualify as the same type as the original? If so, why is the fact that something is a reference, stored in its type?
Edit: if references are a different type, why can they be substituted for the original type in so many situations, without explicit casting? Is there implicit cast involved?
Example:
void bar(int& a);
int x;
int& y = x;
bar(y) // matching type
bar(x) // what happened here? was x cast to a reference?
A reference is formally a type; or at least you can read things like "if T is a reference type" in the C++ standard itself.
However, your question is perfectly legitimate in that references have very confusing semantics. They are not quite first-class types (for example, you can't have a reference-to-reference or a pointer-to-reference), and in my opinion that's because C++ managed to conflate two different kinds of types with how it defines and uses references.
What a reference really does is it gives an alternate name to an already-existing object (value). What does this mean? It means that it doesn't "qualify" the type of the value it refers to per se; it rather qualifies the name ("variable", "storage") itself that is used for referencing the value.
In C++, the semantics of a type and a value often depends on additional properties of the storage where the object/value is stored. This is not always explicit, and that's what confuses people.
I think because C++ heavily relies on exposing the concept of "storage" (rather than hiding it as an implementation detail), there really should be two type systems: one for pure values themselves, and one for storage, where the type system for storage should be a superset of the type system for values.
Another example where a very similar issue appears is CV-qualification. It's not an object/value itself that should be const or volatile. It's the storage containing that value that may or may not be mutable, and may or may not need to be protected from certain load/store optimizations. Again, this could be better expressed if there was a way to express these properties of types separately in the case of values and storage.
From what I can tell, references can be used wherever the original type can
That is simply not true.
Consider:
void foo(int x);
void bar(int& x);
foo(3);
bar(3); // whoops!
And how about this:
struct T
{
int& x;
};
It wouldn't make sense not to have a distinct type for references. This way, you get function overloading powers and every other benefit that the type system gives you.
You would otherwise need to invent some other mechanism to denote a thing as being a reference rather than a non-reference; surely the type system is the perfect mechanism to denote that?
int and int& are two distinct types.
” From what I can tell, references can be used wherever the original type can
No. A reference refers. You can think of it as a pointer in disguise.
” Are references separate types in C++?
Yes.
” If not, why are they written in the type?
That's just the syntax for specifying a reference type, using & as a type builder symbol. As another example, * is a type builder for pointers. Except for a limitation of type inference we could now replace that (1)impractical syntax with template syntax.
1) Both the creators of C and the creator of C++ have on several occasions described the original C declaration syntax as a “failed experiment”.
Unlike a pointer, a reference cannot be reseated; the address it is referencing cannot be changed. By like a pointer, the reference is useful when avoiding copying semantics, thus needing to create an alias to something that already exists... i.e., knowing it is a reference and not an object means the compiler knows not to copy the object at assignment or when passing through functions.
EDIT: regarding the updated questions, "if references are a different type, why can they be substituted for the original type in so many situations, without explicit casting? Is there implicit casting involved?" ... not casting, it is a reference so it simply gets "dereferenced" by "pointing" to the original object; it may help to just think of it as just a substitution name, or an alias, etc.
My understanding: Compound type is composed of primitive and other compound types. I understand that arrays, functions, classes, unions and enumerations are compound types. Why is a pointer a compound? What primitive types is it composed of?
I believe the rationale can be found in the standard under "Basic concepts" (section 3 in C++14, for example):
Finally, this clause presents the fundamental types of the language and lists the ways of constructing compound types from these.
Hence a compound type is really just a type created from another underlying type. A pointer certainly meets that definition since you construct pointer-to-T from T.
In terms of history, it's likely that this was carried over from C since it has the same concept, though it refers to the types and object/function and derived types. Derived types there seems to mirror the same things (at least those things that are common across both languages), including pointers.
A pointer is compound type because it stores both a memory address and a data type. Answer from Murach’s C++ Programming book.
Pointer point to different type is different, so pointer contain some information about the type it point to.And pointer has 2 special function at least, they are * and ->.
Of cause, int,char have some function, something different is that you just need to know "it is int" or "it is char" for those, but when you try using * or ->, knowing "it is pointer" and nothing is infeasible (and pointer++ need to know size of its type).
In fact, every thing in object-oriented method should be regarded as compound types(or we call it class more often) , because you always need to do something using data(otherwise, the existence of data makes no sense), if so, what you are try to do is suggested that appear as method in class, since it is OOM.
I'm not asking the difference between pointer and reference. Just a bit confused about the difference between reference and alias.
As far as I'm concerned, reference is a data type while alias is just a word describing the utility of this data type?
Thanks!
Aliasing refers to any way to refer to the same data through different names. References and pointers are two ways of achieving this behavior.
No, a reference is not a data-type, a reference references some other variable. Using a reference is the same as using the variable it references. It's very similar to a pointer (and it's not unlikely that the compiler treats references as pointers under the hood).
I've never heard of "alias" by itself in the context of C++, but there are type-aliases, created by e.g. typedef or using. There's also aliasing which is unrelated to both references and type-aliases.
Sorry, you said you were not asking the difference between a pointer and a reference.
To answer what you’re asking, the word reference means that a variable is pointing to a location in memory. Alias has a few different meanings, but the one I’ve seen most often in this context is that more than one variable are referencing the same location in memory, such as when you try to call memcpy(p, p, n);. One way to make this happen is with a C++ reference, which is a term of art for a language feature similar but not identical to pointers. Not every reference in C++ necessarily refers to something which ever has another name. You can also do aliasing with pointers, the address operator, a call by reference, or the compiler merging constants so that "Hello" and "Hello" in two places point to the same bytes in memory, or unions. Probably not exhaustive.
If people want to call a reference to something an “alias” even when there isn't any other variable referencing the same memory at the same time, I’m not strongly motivated to argue.
As several others have pointed out, C++14 uses the term “alias” to refer to template types declared with using. (http://en.cppreference.com/w/cpp/language/type_alias)
A type alias declaration introduces a name which can be used as a synonym for the type denoted by type-id. It does not introduce a new type and it cannot change the meaning of an existing type name. There is no difference between a type alias declaration and typedef declaration. This declaration may appear in block scope, class scope, or namespace scope.
From http://en.cppreference.com/w/cpp/language/type_alias
From what I can tell, references can be used wherever the original type can (I'm not implying the reverse is true), the only difference is their mutation semantics (when the variables are used as lvalues).
Wouldn't they then qualify as the same type as the original? If so, why is the fact that something is a reference, stored in its type?
Edit: if references are a different type, why can they be substituted for the original type in so many situations, without explicit casting? Is there implicit cast involved?
Example:
void bar(int& a);
int x;
int& y = x;
bar(y) // matching type
bar(x) // what happened here? was x cast to a reference?
A reference is formally a type; or at least you can read things like "if T is a reference type" in the C++ standard itself.
However, your question is perfectly legitimate in that references have very confusing semantics. They are not quite first-class types (for example, you can't have a reference-to-reference or a pointer-to-reference), and in my opinion that's because C++ managed to conflate two different kinds of types with how it defines and uses references.
What a reference really does is it gives an alternate name to an already-existing object (value). What does this mean? It means that it doesn't "qualify" the type of the value it refers to per se; it rather qualifies the name ("variable", "storage") itself that is used for referencing the value.
In C++, the semantics of a type and a value often depends on additional properties of the storage where the object/value is stored. This is not always explicit, and that's what confuses people.
I think because C++ heavily relies on exposing the concept of "storage" (rather than hiding it as an implementation detail), there really should be two type systems: one for pure values themselves, and one for storage, where the type system for storage should be a superset of the type system for values.
Another example where a very similar issue appears is CV-qualification. It's not an object/value itself that should be const or volatile. It's the storage containing that value that may or may not be mutable, and may or may not need to be protected from certain load/store optimizations. Again, this could be better expressed if there was a way to express these properties of types separately in the case of values and storage.
From what I can tell, references can be used wherever the original type can
That is simply not true.
Consider:
void foo(int x);
void bar(int& x);
foo(3);
bar(3); // whoops!
And how about this:
struct T
{
int& x;
};
It wouldn't make sense not to have a distinct type for references. This way, you get function overloading powers and every other benefit that the type system gives you.
You would otherwise need to invent some other mechanism to denote a thing as being a reference rather than a non-reference; surely the type system is the perfect mechanism to denote that?
int and int& are two distinct types.
” From what I can tell, references can be used wherever the original type can
No. A reference refers. You can think of it as a pointer in disguise.
” Are references separate types in C++?
Yes.
” If not, why are they written in the type?
That's just the syntax for specifying a reference type, using & as a type builder symbol. As another example, * is a type builder for pointers. Except for a limitation of type inference we could now replace that (1)impractical syntax with template syntax.
1) Both the creators of C and the creator of C++ have on several occasions described the original C declaration syntax as a “failed experiment”.
Unlike a pointer, a reference cannot be reseated; the address it is referencing cannot be changed. By like a pointer, the reference is useful when avoiding copying semantics, thus needing to create an alias to something that already exists... i.e., knowing it is a reference and not an object means the compiler knows not to copy the object at assignment or when passing through functions.
EDIT: regarding the updated questions, "if references are a different type, why can they be substituted for the original type in so many situations, without explicit casting? Is there implicit casting involved?" ... not casting, it is a reference so it simply gets "dereferenced" by "pointing" to the original object; it may help to just think of it as just a substitution name, or an alias, etc.
My question is simple: What are void pointers for in C++? (Those things you declare with void* myptr;)
What is their use? Can I make them point to a variable of any type?
Basically, a remnant from C.
What is their use?
In C, they were and are used widely, but in C++ I think they are very rarely, if ever, needed, since we have polymorphism, templates etc. which provide a much cleaner and safer way to solve the same problems where in C one would use void pointers.
Can I make them point to a variable of any type?
Yes. However, as others have pointed out, you can't use a void pointer directly - you have to cast it into a pointer to a concrete data type first.
Yes, this is a C construct (not C++-specific) that allows you to declare a pointer variable that points to any type. You can't really do much of anything with such a pointer except cast it back to the real object that it actually points to. In modern C++, void* has pretty much gone out of fashion, yielding in many cases to template-based generic code.
About one of the few uses that exist for void pointers in C++ is their use in overloading the new operators. All new operators return type void* by definition. Other than that, what others have said is true.
From cplusplus.com:
The void type of pointer is a special
type of pointer. In C++, void
represents the absence of type, so
void pointers are pointers that point
to a value that has no type (and thus
also an undetermined length and
undetermined dereference properties).
This allows void pointers to point to
any data type, from an integer value
or a float to a string of characters.
But in exchange they have a great
limitation: the data pointed by them
cannot be directly dereferenced (which
is logical, since we have no type to
dereference to), and for that reason
we will always have to cast the
address in the void pointer to some
other pointer type that points to a
concrete data type before
dereferencing it.
Type hiding. It does still have its valid uses in modern C++. Dig through the source code in boost and you'll find a few. Generally the use of a void* is buried very deep within the bowels of a more complex construct that ensures the type safety of the interface while doing black and evil magic within.
They did once in C perform the job of being the pointer-to-anything, a pointer you passed in to libraries and they gave back out to you as userdata. A void* is no use at all without the programmer knowing their context in some fashion, since you don't know what's on the other end, you can't do anything with the data. Except pass the pointer to some other code that does know.
What I don't understand is why people didn't just use undefined types, i.e. opaque pointers. Type safety, user data.
In modern C++, the pointer-to-void is nearly entirely superseded by polymorphism and template-generated generic code. However, you may still have to use them to interface with native C code. To use a void* safely, in any given context, only ever cast one type to a void*. That way, you know for sure what it points to. If you need more types, you could do a quick
struct safevoidptr {
base* ptr
}; or struct safevoidptr { void* ptr; int type; };
I believe that dynamic_cast might also be able to convert void* to polymorphic types, although I have never used dynamic_cast, so don't take my word for it.
A void pointer can point to anything, as long as its memory :-)
The C standard states that you can convert any pointer to a void-pointer, then cast it back without losing anything.
A pointer to void is the closest concept to an assembly language pointer. It is a generic pointer that reserves space for an address or location of something (function or datum). As others have stated, it must be cast before it can be dereferenced.
The void pointer is a popular tool for representing Object Orient concepts in the C language. One issue with the void pointer is that the content may not match the receiver's perception. If the caller sets the pointer to point to a square, but the receiving function is expecting a pointer to a cat, undefined and strange things will happen with the pointer is cast.
Since there are already so many good answers, I'd just provide one of the more common one I saw: template specialization. If I don't recall wrongly, Stroustrup book has an example of this: specializing vector as vector, then having vector to derive (privately) from vector. This way, vector will only contain straightforward easily inlined codes (i.e. call relevant functions from vector). This will reduce the number of duplication when vector is compiled in a program that uses it with many different types of pointers.
void ptr is basically an empty box. Fill it with whatever you want but make sure you label it(tupecasting)
I use them in my dynamic lists to hold more types of objects (all are pointers).
typedef void* Object;
Then when you declare a Object variable you can store any pointer in it.
It's more or less usefull depending on the needs.
I find it very usefull when you have to store any pointer somewhere and you can't just derive all your classes from just one. Other than that as the others said it's better to use templates, polimorphism etc.
Things you could do in C with void, but can't in C++ :
void*'s are automatically converted to other pointer types. (You know its a void* - you gain no type safety from forcing an explicit cast)
Struct* p = malloc( sizeof(Struct) );
// vs C++
Struct* p = (Struct*)malloc( sizeof(Struct) );
// Some will argue that that cast style is deprecated too, and c++ programmers
// need to actually do this:
Struct* p = reinterpret_cast<Struct*>malloc( sizeof(Struct) );
// See what C++ did there? By making you write Struct a 3rd time, you can now be sure
// you know what you are doing!
void*'s also did indirection counting in C, allowing greater safety when passing pointers to functions that take a pointer to a pointer.
void funcInitializingOutPtr( void** ppOut)
{
*ppOut = malloc( x );
}
int* out = NULL;
funcInitializingPtr(out); // C would signal this as an error
funcInitializingPtr(&out); // correct
// vs C++
funcInitializingPtr( (void**)&out ); // so much safer needing that exlicit cast.
funcInitializingPtr( (void**)out); // oops. thanks C++ for hiding the common error
I belive void* is memory location where you can typecast/Store anything. I some Language Pundit will disagree on this with me. but i have used it successfully in many of my project.
Only problem i see is of typesafety