Could someone explain the logic behind this? Why void? For example
#include <iostream>
using namespace std;
int main()
{
char c;
cout << (void *)&c;
return 0;
}
Could someone explain the logic behind this? Why void? For example
#include <iostream>
using namespace std;
int main()
{
char c;
cout << (void *)&c;
return 0;
}
cout << (void *)&c;
takes the address of c, then casts it to void*, then prints pointer.
The intent here is to print the address of variable c. But when passing a char * to std::cout << it will attempt to print a null-terminated string. To avoid this (and print the actual address) you have to cast to void* first.
More explanation:
std::ostream::operator<< has overload (2) that handles char * and const char*. It assumes that a const char* will point to some string that is eventually terminated by a null-character '\0'. That's simply a convention used in C and C++.
You want to avoid this and instead use overload (7) to print the address.
The operator << is overloaded for objects of the type char * such a way that it outputs characters as if the used pointer is a pointer to the first character of a C-string (a sequence of characters terminated by the zero character '\0').
And the expression &c without casting has the type char *. So the operator assumes that the passed pointer expression &c supplies a pointer to a C-string.
To output the address of the object c you need to cast the expression &c to the type void *.
Here is a simple program that demonstrates the difference.
#include <iostream>
int main()
{
const char *s = "Hello";
std::cout << s << '\n';
std::cout << static_cast<const void *>( s ) << '\n';
return 0;
}
The program output is
Hello
0x5598fd4a3004
Why does
(void *)&get the address of the variable?
The unary & is the addressof operator. The addressof operator gets the address of the operand because that's the purpose of that operator.
Why void?
Because
The type of &c is char*, and pointers of that type are treated by the output stream as a pointer to a null terminated character string, which are handled differently from all other pointers. Specifically, the content of the string would be output. Inserting a char* that isn't a pointer to a null terminated character string into a character stream would result in undefined behaviour. &c is not a pointer to a null terminated character string. Inserting a pointer of another type into a character stream will instead result in the output of a numerical representation of the address.
The example converts &c to another pointer type so that it won't be treated as a null terminated character string.
All object pointers can be converted to void*, so that is the pointer type that is conventionally chosen for outputting the address of a character.
For a bit more detail, the character stream insert operator has overloads:
operator<<(ostrea&, const char*);
operator<<(ostrea&, const void*); // I'm cheating a bit
// this is technically a member overload
So would I need to convert it to void* when and only when a variable is NULL?
Not at all. The variable c isn't null. And whether a pointer is null has no influence on whether or not it needs to be converted to void*.
Also note that null terminator character - which terminates a null terminated string - is not a null pointer. And a null pointer is not a pointer to a null terminator character. Those are entirely different concepts.