2017-02-15 5 views
2

Имеет ли следующий фрагмент кода неопределенное поведение? Код только пытается заполнить структуру sockaddr_storage с форматным форматом sockaddr_in, а затем прочитать его обратно через тот же тип, то есть. sockaddr_in. Также в следующих вызовах структура sockaddr_storage передается с литой до sockaddr структурой. Я видел подобный вопрос и задавался вопросом, содержит ли этот код этот код. Эта программа отлично работает везде, где я тестировал -UB с литой конструкцией различных типов?

Run Online

#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <iostream> 

using namespace std; 

void fillAF_INET(sockaddr_storage &s){ 
    sockaddr_in *p = reinterpret_cast<sockaddr_in *>(&s); 
    p->sin_family = AF_INET; 
    p->sin_port = htons(10000); 
    inet_pton(AF_INET, "127.0.0.1", &p->sin_addr); 
} 

// void fillAF_INET6(sockaddr_storage &s){...} 
// void fillAF_UNIX(sockaddr_storage &s){...} 

int main(){ 
    sockaddr_storage s; 
    fillAF_INET(s); 

    sockaddr_in *p = reinterpret_cast<sockaddr_in *>(&s); 
    std::cout << ntohs(p->sin_port) << " "; 
    std::cout << boolalpha << (p->sin_family == AF_INET); 

    int sock = socket(AF_INET, SOCK_STREAM,0); 
    int r = bind(sock, (sockaddr *)&s, sizeof(s)); 
    // further calls 

    return 0; 
} 

Результат приходит: 10000 true, абсолютно правильно!

+0

удаленная обработка ошибок для ее хранения .. –

+0

похоже: http://stackoverflow.com/questions/9964418/strict-aliasing-and-alignment –

ответ

3

Код верный. Вот что Open Group говорит о sockaddr_storage:

<sys/socket.h> Заголовок должен определить sockaddr_storage структуру. Эта структура должна быть:

  • достаточно большой, чтобы вместить всех поддерживаемых протокольно-конкретный адрес структуры

  • Унифицированные на соответствующей границе, так что указатели на него могут быть отлиты как указатели на протокол конкретных структуры адреса и используется для доступа полей этих структур без проблем выравнивания

+2

«Это правильно» - вы имеете в виду, что это UB или код правильный и это не UB? См. Также https://stackoverflow.com/questions/42178179/will-casting-around-sockaddr-storage-and-sockaddr-in-break-strict-aliasing – harmic

+1

Это неправильно, см. Также - http://stackoverflow.com/вопросы/42176962/заполнить SOCKADDR-хранения-структура-с-значениями-в-SOCKADDR-в –

Смежные вопросы