anon
anon

Reputation: 43

Why does `(void *)&` get the address of the variable?

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;
}

Upvotes: 4

Views: 590

Answers (3)

eerorika
eerorika

Reputation: 238341

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

  1. 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.

  2. 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.

Upvotes: 2

Lukas-T
Lukas-T

Reputation: 11340

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.

Upvotes: 6

Vlad from Moscow
Vlad from Moscow

Reputation: 310980

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

Upvotes: 4

Related Questions