2017-02-15 44 views
2

以下代碼段是否包含未定義的行爲?該代碼只會嘗試用sockaddr_in結構格式填充sockaddr_storage結構,然後通過相同類型(例如,)讀取它。 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

代碼無誤。這裏是開放組織說,大約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-在 –