Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Why does casting as a pointer and then dereferencing work?

Recently I have been working on sockets in C++ and I have come across this:

*(struct in_addr*)&serv_addr.sin_addr.s_addr = *(struct in_addr *)server->h_addr;

While this does do what I want it to I am a little confused as to why I can't do this:

(struct in_addr)serv_addr.sin_addr.s_addr = *(struct in_addr *)server->h_addr;

Since it becomes a pointer and then immediately is dereferenced shouldn't the second work as well as the first? I am still new to C++ and this is a little confusing to me. Any help would be greatly appreciated. Below is the code. All it does is takes the host name or IP and prints the IP to the screen.

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>


using namespace std;

int main(){

    int socketfd, portno, rwResult; 
    struct sockaddr_in serv_addr; 
    struct hostent* server;     
    char inputName[50];

    //The next block gets the host name and port number and stores them in variables
    cout<<"Enter host(Max Size 50): ";
    cin>>inputName;
    cout<<endl<<"Enter port number: ";
    cin>>portno;
    cout<<endl;

    server = gethostbyname(inputName);
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(portno);

    *(struct in_addr*)&serv_addr.sin_addr.s_addr = *(struct in_addr *)server->h_addr;
    //This is where I am confused
    //(struct in_addr)serv_addr.sin_addr.s_addr = *(struct in_addr *)server->h_addr;


    cout<< "Server: "<<inet_ntoa(*(struct in_addr *)server->h_addr_list[0])<<endl;

    cout<< "Server: "<<inet_ntoa(*(struct in_addr *)&serv_addr.sin_addr.s_addr)<<endl;
    //The two cout's tell me if the address was copied correctly to serv_addr I believe.



    return 0;
}
like image 867
Hudson Worden Avatar asked Dec 28 '22 13:12

Hudson Worden


1 Answers

Objects can only be cast as another class if a constructor exists which accepts an argument of the original type.

Pointers, on the other hand, can be cast willy nilly. However, it can be very dangerous to do so. If it is necessary to cast, use static_cast or dynamic_cast when doing so, and potentially check to see if the cast was successful. One additional stylistic advantage to casting in this more explicit fashion is it makes the cast more blatant to someone browsing your code.

like image 197
loki11 Avatar answered Jan 13 '23 12:01

loki11