Why a reference is likely as an object? - c++

Currently learning c++ and nowhere else better to ask something than to the experts of S.O. I Couldn't find more complete and better answers than here. So there it goes.
DWORD dw = 5;
cout << &dw;
Displays the address where the value of dw is stored.
But then why:
void Display( DWORD &dwUserId )
{
cout << dwUserId;
}
int _tmain( int argc, _TCHAR* argv[] )
{
DWORD dw = 5;
Display( dw );
}
Why on this example it is displayed the value of dw and not dw address?

& has two different meanings in this context:
placed in a declaration, it means the variable is a reference. In your case, you pass the parameter by reference.
outside a declaration, before a variable, it takes its address.
Besides these, it can also mean the bitwise AND operator
int x;
int& y = x; //y is a reference to x
int* z = &x; //& takes the address of x and assigns it to z
y & x; //bitwise AND

DWORD &dwUserId as a parameter to a function is a reference to DWORD.
In C++, the & operator does two things, depending on context:
When used in an r-value expression, it returns the address-of a value. e.g. void* ptr = &myObject;
When used in a type specifier it modifies the type to be a "reference-of" type. This is similar to how references work in Java and .NET. e.g. int& ref = myInt;
In your case, your dwUserId parameter is actually of type "reference to DWORD".
If you want to change it to get the address then do this:
void Display(DWORD* userId) {
cout << userId;
}
Display( &dw );
Also, please void TCHAR types. MBCS is deprecated. Win32 Unicode and wchar_t is the future :) Also avoid Hungarian notation. This isn't the 1980s. We have IDEs now.

Because when you use the & sign before a parameter name on a function definition you are telling the compiler to pass that parameter as a reference, i.e., don't make a copy of it.
When you use it before a variable name somewhere in the code you are telling the compiler to use the variable address instead of his value.

Related

Why can't we use a void* to operate on the object it addresses

I am learning C++ using C++ Primer 5th edition. In particular, i read about void*. There it is written that:
We cannot use a void* to operate on the object it addresses—we don’t know that object’s type, and the type determines what operations we can perform on that object.
void*: Pointer type that can point to any nonconst type. Such pointers may not
be dereferenced.
My question is that if we're not allowed to use a void* to operate on the object it addressess then why do we need a void*. Also, i am not sure if the above quoted statement from C++ Primer is technically correct because i am not able to understand what it is conveying. Maybe some examples can help me understand what the author meant when he said that "we cannot use a void* to operate on the object it addresses". So can someone please provide some example to clarify what the author meant and whether he is correct or incorrect in saying the above statement.
My question is that if we're not allowed to use a void* to operate on the object it addressess then why do we need a void*
It's indeed quite rare to need void* in C++. It's more common in C.
But where it's useful is type-erasure. For example, try to store an object of any type in a variable, determining the type at runtime. You'll find that hiding the type becomes essential to achieve that task.
What you may be missing is that it is possible to convert the void* back to the typed pointer afterwards (or in special cases, you can reinterpret as another pointer type), which allows you to operate on the object.
Maybe some examples can help me understand what the author meant when he said that "we cannot use a void* to operate on the object it addresses"
Example:
int i;
int* int_ptr = &i;
void* void_ptr = &i;
*int_ptr = 42; // OK
*void_ptr = 42; // ill-formed
As the example demonstrates, we cannot modify the pointed int object through the pointer to void.
so since a void* has no size(as written in the answer by PMF)
Their answer is misleading or you've misunderstood. The pointer has a size. But since there is no information about the type of the pointed object, the size of the pointed object is unknown. In a way, that's part of why it can point to an object of any size.
so how can a int* on the right hand side be implicitly converted to a void*
All pointers to objects can implicitly be converted to void* because the language rules say so.
Yes, the author is right.
A pointer of type void* cannot be dereferenced, because it has no size1. The compiler would not know how much data he needs to get from that address if you try to access it:
void* myData = std::malloc(1000); // Allocate some memory (note that the return type of malloc() is void*)
int value = *myData; // Error, can't dereference
int field = myData->myField; // Error, a void pointer obviously has no fields
The first example fails because the compiler doesn't know how much data to get. We need to tell it the size of the data to get:
int value = *(int*)myData; // Now fine, we have casted the pointer to int*
int value = *(char*)myData; // Fine too, but NOT the same as above!
or, to be more in the C++-world:
int value = *static_cast<int*>(myData);
int value = *static_cast<char*>(myData);
The two examples return a different result, because the first gets an integer (32 bit on most systems) from the target address, while the second only gets a single byte and then moves that to a larger variable.
The reason why the use of void* is sometimes still useful is when the type of data doesn't matter much, like when just copying stuff around. Methods such as memset or memcpy take void* parameters, since they don't care about the actual structure of the data (but they need to be given the size explicitly). When working in C++ (as opposed to C) you'll not use these very often, though.
1 "No size" applies to the size of the destination object, not the size of the variable containing the pointer. sizeof(void*) is perfectly valid and returns, the size of a pointer variable. This is always equal to any other pointer size, so sizeof(void*)==sizeof(int*)==sizeof(MyClass*) is always true (for 99% of today's compilers at least). The type of the pointer however defines the size of the element it points to. And that is required for the compiler so he knows how much data he needs to get, or, when used with + or -, how much to add or subtract to get the address of the next or previous elements.
void * is basically a catch-all type. Any pointer type can be implicitly cast to void * without getting any errors. As such, it is mostly used in low level data manipulations, where all that matters is the data that some memory block contains, rather than what the data represents. On the flip side, when you have a void * pointer, it is impossible to determine directly which type it was originally. That's why you can't operate on the object it addresses.
if we try something like
typedef struct foo {
int key;
int value;
} t_foo;
void try_fill_with_zero(void *destination) {
destination->key = 0;
destination->value = 0;
}
int main() {
t_foo *foo_instance = malloc(sizeof(t_foo));
try_fill_with_zero(foo_instance, sizeof(t_foo));
}
we will get a compilation error because it is impossible to determine what type void *destination was, as soon as the address gets into try_fill_with_zero. That's an example of being unable to "use a void* to operate on the object it addresses"
Typically you will see something like this:
typedef struct foo {
int key;
int value;
} t_foo;
void init_with_zero(void *destination, size_t bytes) {
unsigned char *to_fill = (unsigned char *)destination;
for (int i = 0; i < bytes; i++) {
to_fill[i] = 0;
}
}
int main() {
t_foo *foo_instance = malloc(sizeof(t_foo));
int test_int;
init_with_zero(foo_instance, sizeof(t_foo));
init_with_zero(&test_int, sizeof(int));
}
Here we can operate on the memory that we pass to init_with_zero represented as bytes.
You can think of void * as representing missing knowledge about the associated type of the data at this address. You may still cast it to something else and then dereference it, if you know what is behind it. Example:
int n = 5;
void * p = (void *) &n;
At this point, p we have lost the type information for p and thus, the compiler does not know what to do with it. But if you know this p is an address to an integer, then you can use that information:
int * q = (int *) p;
int m = *q;
And m will be equal to n.
void is not a type like any other. There is no object of type void. Hence, there exists no way of operating on such pointers.
This is one of my favourite kind of questions because at first I was also so confused about void pointers.
Like the rest of the Answers above void * refers to a generic type of data.
Being a void pointer you must understand that it only holds the address of some kind of data or object.
No other information about the object itself, at first you are asking yourself why do you even need this if it's only able to hold an address. That's because you can still cast your pointer to a more specific kind of data, and that's the real power.
Making generic functions that works with all kind of data.
And to be more clear let's say you want to implement generic sorting algorithm.
The sorting algorithm has basically 2 steps:
The algorithm itself.
The comparation between the objects.
Here we will also talk about pointer functions.
Let's take for example qsort built in function
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))
We see that it takes the next parameters:
base − This is the pointer to the first element of the array to be sorted.
nitems − This is the number of elements in the array pointed by base.
size − This is the size in bytes of each element in the array.
compar − This is the function that compares two elements.
And based on the article that I referenced above we can do something like this:
int values[] = { 88, 56, 100, 2, 25 };
int cmpfunc (const void * a, const void * b) {
return ( *(int*)a - *(int*)b );
}
int main () {
int n;
printf("Before sorting the list is: \n");
for( n = 0 ; n < 5; n++ ) {
printf("%d ", values[n]);
}
qsort(values, 5, sizeof(int), cmpfunc);
printf("\nAfter sorting the list is: \n");
for( n = 0 ; n < 5; n++ ) {
printf("%d ", values[n]);
}
return(0);
}
Where you can define your own custom compare function that can match any kind of data, there can be even a more complex data structure like a class instance of some kind of object you just define. Let's say a Person class, that has a field age and you want to sort all Persons by age.
And that's one example where you can use void * , you can abstract this and create other use cases based on this example.
It is true that is a C example, but I think, being something that appeared in C can make more sense of the real usage of void *. If you can understand what you can do with void * you are good to go.
For C++ you can also check templates, templates can let you achieve a generic type for your functions / objects.

How references in C++ are implemented with pointers

I've heared that C++ reference variables are implemented using pointers. I've been looking at some C code a while before i started with C++, I would because of that like to have something which i can relate to in the C language. Does anyone actually have an example on how it is implemented using pointers?
I've been doing some research on the question, this is what i've found. However, i'm not sure if it is legit or not as i've not been able to run this properly in a C++ file before. Any answers will be appreciated, thanks! :)
int& = *(int const *)
A reference has the same meaning as a constant pointer.
The code for references and pointers is the same, at least with MSVC2013.
For example:
int u=1,v=3, w;
int& x = u; // initialize reference
w = x; // x is synonym for u;
x++;
int *y = &u; // initalize pointer
w = *y; // y points to u
(*y)++;
The initialisation generates in both case:
lea eax, DWORD PTR _u$[ebp]
mov DWORD PTR _x$[ebp], eax ; of course in the case of the pointe _y$ instead of _x$.
The assignment, in both case generates:
mov eax, DWORD PTR _x$[ebp]
mov ecx, DWORD PTR [eax]
mov DWORD PTR _w$[ebp], ecx
And even the increment generates the same code.
The code generated is the same for whether it is a pointer, a const pointer, or a poitner to const (in the latter case, the ++ does not work). It's the compiler buisness to make sure that const is const.
Now there is a subtle difference in syntax:
int& x = u; // initialize reference
int *y = &u; // initalize pointer
int const *z = &u; // initialize pointer to "const int". Pointer itself is not const !
int * const a = &u; // initialize "const pointer" to "int", which is basically a reference.
With these definitions:
//(*z)++; // invalid because the it points to a const int.
z = &w; // valid because pointer intself is not const
and:
(*a)++; // valid because the it points to an int.
// a = &w; // invalid because it's a const pointer
So you could say int& is pretty much equivalent to int * const (I don't use '=' here, because it is reserved to the operator= and looks like a syntax error !)
Of course, with the reference you always use its name as if it was a real variable (ex: x++) while with the const pointer you always have to dereference (aka: (*x)++). So same meaning, but different syntax.
This is the best proof I can think of:
#include <iostream>
using namespace std;
double value;
struct pointer {
double *value; };
struct reference {
double& value; };
int main() {
pointer ptr { &value };
reference ref { value };
*ptr.value = 3.14;
cout << sizeof(value) << endl;
cout << sizeof(pointer) << endl;
cout << sizeof(reference) << endl;
cout << ref.value;
}
Output:
8
4
4
3.14
Can you see the sizes? sizeof(pointer) == sizeof(reference) but not sizeof(value).
Regarding that added/edited example in the question int& = *(int const *):
ref.value = *ptr.value; ref.value = *(double*)ref.value; //no const
ref.value = *(double const *)ptr.value; // yes, we can add const before *
int i = 1; const j = 2;
const int& cri = *(const int const *)&i; // same as *&i and simple i, notice two consts
const int& crj = j;
int& rj = j; // error: const cannot be removed that way
In other words: References are constant pointers (cannot be changed) with a different set of operators. The main advantage is that compilers can optimize them better (discard the reference/pointer completely), but that does not proof that they are any different because compilers can optimize/discard pointers as well (and gcc -O3 can do that well, I have seen and dissassembled good loop with pointers, where gcc could overcome so called aliasing problem).
A compiler can implement references any way that works, including that some references are completely optimized away.
You can think of the reference
T& r = o;
as
T* const pr = &o;
#define r (*pr)
which serves as a nice explanation of most properties of lvalue references, except that this conceptual picture does not include lifetime extension of temporaries and initialization with a temporary.
It “explains” that
a reference must be initialized in the declaration, except when it’s a formal argument,
a reference can’t be reassigned,
a reference can’t be a “null-reference” in valid code.
But keep in mind that it’s only a conceptual picture: while it’s very likely to be the underlying reality for much of the generated code, it is by no means a requirement that a compiler implements a reference this way.
You might find the section about references in the C++ FAQ instructive.
In C, when you use a variable as a parameter to a function, it is sent by value. If the function is supposed to change the variable, then the parameter must be sent as a pointer.
int x = 5;
void addtwo(int* param)
{
*param += 2;
}
addtwo(&x); // This will send a pointer to x to the function addtwo
In C++, you can send a reference:
void addtwo(int& param)
{
param += 2;
}
addtwo(x); // This will send a reference to x to the function addtwo
This doesn't look like much of a difference in this simple example, but in the second one, it looks like param is not being dereferenced. But it actually is, since it was sent as a reference. Even though param does not look like a pointer (and it isn't - it's a reference) the function addtwo is sent the address of x, very much as if it were a pointer. The difference is subtle, but concrete.

C++ Guidance: Understanding How Pointers Work

I found a code snippet on the internet. When I compile and run it, the output is 70. but i don't know whats happening in the code. please help me out.
#include <iostream>
using namespace std;
void doubleNumber (int *num )
{
*num = *num * 2;
}
int main ()
{
int num = 35;
doubleNumber (&num) ;
cout <<num ;
return 0;
}
void doubleNumber (int *num ) takes a pointer to an integer as parameter, which permits the method to modify the original variable.
Calling *num dereferences the pointer, while *num = *num * 2 assigns the value of the variable of the pointer num multiplied by 2 to the memory cell where num points to.
And in the main, where you have declared the integer, by calling the function doubleNumber with &num, you reference the variable and the return value of that is the pointer to the variable.
int num = 35;
doubleNumber(&num);
Is equivalent to:
int num = 35;
int* num_pointer = &num;
doubleNumber(num_pointer);
You should probably take a look at this site to read about referencing and dereferencing.
In your main function you call doubleNumber() passing a pointer to num.
The doubleNumber() function receives the pointer and doubles his value.
*num = *num * 2
The code defines a function which "doubles" an number. The main program passes the pointer to the variable num in to the function, and the function doubles the variable using the pointer passed in.
Pointers in C++ are my favorite (and - for newer programmers - are often confusing because they are learned in tandem with referencing (& operator). The * symbol is used for a lot of 'stuff' in C++, and it is not helped by the fact that, with pointers, the * symbol does two different things, for which we have two (2) names: dereferencing and indirection.
When we declare a pointer to a type, e.g. int *intPtr = //CODE HERE, we enable the variable to accept an address *intPtr and assign the address in memory of the rvalue (that on the right side of the binary operator) to the variable intPtr. intPtr - or, the address of the rvalue - can then, itself, be passed around and used as an lvalue. We call this "dereferencing".
Then, when we want to access the value of the thing stored at the memory address, we use the indirection operator * in the body of the code to access the stored value. So, let's say we do this:
int num = 35;
int num2 = 0;
int *intPtr = &num; // here using the reference operator & to assign the address
// of num to intPtr
We can then access the value stored behind num by going:
num2 = *intPtr;
Here, the * indirection operator is actually doing something else: it is used to access the value stored at the address stored in intPtr.
WHERE THE CONFUSION HAPPENS:
So, when we see a function header with a pointer as an argument, it's like "Wha'? Which * is being used?"
returntype functionIdentifier(type *num)
In this case, what is received as an argument is a memory address. Then, the argument can be used throughout the body of the function. Too, the indirection operator * can be used to access the value stored at the memory address stored in the passed-in argument (pointer - in this came num).

putting a '&' after the type [duplicate]

This question already has answers here:
ampersand (&) at the end of variable etc
(5 answers)
Closed 3 years ago.
I am fairly new to programming. I am just moving on to C++ from C in my college courses, and I encountered something that I haven't seen before in C. Sometimes after the type, either in a function declaration or passing a parameter, a & immediately follows the type. For example, we use a struct called Customer in one of our projects, and some of the functions pass Customer&. Why is the ampersand after the type, as opposed to in front? Thanks!
References in C++ simply allow for a cleaner way to execute the following code:
int x = 16;
int* y = &x;
cout << *y;
Which could be written instead as
int x = 16;
int& y = x;
cout << y;
When defining functions, a reference allows a function to change the value of parameters without causing the user of the function to put an ampersand before everything. E.g.
void func( int& a )
{
a = 5;
}
void main()
{
int A = 10;
func( A );
cout << A; // Will output '5'
}
Be careful with this type of mutation, as a programmer using functions like this without checking the implementation might not realize that the function is changing the value of the parameters unless the intent is obvious. init_server(my_server) would be an example of a case where it's obvious, but to_json(my_struct) would clearly be an example where you should not be using a reference to change the struct in any way.
But, one of the most important uses of references, would be function like
int sum_vector( const vector<int>& a ) {
int sum = 0;
for( int i = 0; i < a.size(); i++ ) {
sum += a[i];
}
return sum;
}
If you tried to make sum_vector take in a vector, and you passed in a vector with 100 million entries, then it would have to copy them all over, taking forever. You could take in a pointer, but then the internal parts of the function would have to constantly dereference, and it must called with sum_vector(&myvec), which is more annoying than sum_vector(myvec). In this way, using a const reference, you can prevent the highly inefficient copying of the whole vector into the function body, while keeping syntax neat. Using const lets you reassure yourself that you're not going to change the vector that you were given. And, it also assures the user of your function that you won't change it. Similarly, void to_json(const some_struct&) would be a better function definition as it ensures you won't change the user's data.

Initializing pointers in C++

Can assign a pointer to a value on declaration? Something like this:
int * p = &(1000)
Yes, you can initialize pointers to a value on declaration, however you can't do:
int *p = &(1000);
& is the address of operator and you can't apply that to a constant (although if you could, that would be interesting). Try using another variable:
int foo = 1000;
int *p = &foo;
or type-casting:
int *p = (int *)(1000); // or reinterpret_cast<>/static_cast<>/etc
What about:
// Creates a pointer p to an integer initialized with value 1000.
int * p = new int(1000);
Tested and works. ;-)
There are two things not clear in the question to me. Do you want to set the pointer to a specific value (i.e address), or do you want to make the pointer point to some specific variable?
In the latter case, you can just use the address-of operator. The value of the pointer is then set to the address of some_int_variable.
int *p = &some_int_variable;
*p = 10; // same as some_int_variable = 10;
Note: What follows is evil changing of the pointer's value manually. If you don't know whether you want to do that, you don't want to do it.
In the former case (i.e setting to some specific, given address), you can't just do
int *p = 1000;
Since the compiler won't take the int and interpret it as an address. You will have to tell the compiler it should do that explicitly:
int *p = reinterpret_cast<int*>(1000);
Now, the pointer will reference some integer (hopefully) at address 1000. Note that the result is implementation defined. But nevertheless, that are the semantics and that is the way you tell the compiler about it.
Update: The committee fixed the weird behavior of reinterpret_cast<T*>(0) that was suggested by a note and for which i provided a workaround before. See here.
Um. I don't think you can take a non-const address of a constant like that.
but this works:
int x = 3;
int *px = &x;
cout << *px; // prints 3
or this:
const int x = 3;
const int *px = &x;
const int *pfoo = reinterpret_cast<const int*>(47);