2016-09-22 98 views
1

我在編譯C++構建時遇到了一些問題:編譯器收到兩條警告。警告C4715:'d2cs_conn_set_addr':並非所有控制路徑都返回值

connection.c(813):警告C4715: 'd2cs_conn_set_addr':不是所有的控制路徑返回一個值

這其中的代碼點我:

extern int d2cs_conn_set_addr(t_connection * c, unsigned int addr) 
{ 
ASSERT(c,-1); 
c->addr = addr; 
} 

fdwatch_iocp .c(246):警告C4700:使用未初始化的局部變量'ret'

指向這片:

if ((rw & fdwatch_type_read) && !(rw & fdwatch_type_accept) && !(orig_state & fdwatch_type_read)) 

{ 

    memset(tmpev, 0, sizeof(WSAOVERLAPPED)); 

    ret = WSARecv(fdw_fd(fdw_fds + idx), &wsaBuf, 1, &dummy1, &dummy2, (LPWSAOVERLAPPED)tmpev, NULL); 

    if ((ret == -1) && (err = GetLastError()) != 997) 

    { 

     eventlog(eventlog_level_fatal, __FUNCTION__, "cannot update iocp sock %d with read state: %d", fdw_fd(fdw_fds + idx), err); 

     //printf("Error %d on WSARecv\n", err); 

    } 

if (fdw_rw(cfd) & fdwatch_type_read && pending_ev->events == fdwatch_type_read) 
{ 
    if (hnd(fdw_data(cfd), fdwatch_type_read) == -2) 
    { 
     return; 
    } 
    memset(tmpev, 0, sizeof(WSAOVERLAPPED)); 
    WSARecv(fdw_fd(fdw_fds + idx), &wsaBuf, 1, &dummy1, &dummy2, (LPWSAOVERLAPPED)tmpev, NULL); 
    if ((ret == -1) && (err = GetLastError()) != 997) 
    { 
     eventlog(eventlog_level_fatal, __FUNCTION__, "cannot update iocp sock %d with read state: %d", fdw_fd(fdw_fds + idx), err); 
     //printf("Error %d on WSARecv\n", err); 
    } 

我沒有這個代碼,我只是想,沒有錯誤編譯。

+2

你聲明'd2cs_conn_set_addr'返回一個'int',所以你需要滿足這個要求,另一個警告說'ret'沒有被初始化,但是你沒有發佈足夠的代碼來顯示它是如何聲明的 – EdChum

+0

對於第二個,我們需要看到更多的代碼; 「ret」的聲明不在您發佈的代碼片段中。我們需要在聲明和您展示的這種用法之間的一切。 – Angew

+0

'ret'在整個函數中沒有賦值。我認爲只有原作者知道這些功能應該如何工作。 (但是看到代碼在18個月內沒有被觸及,他們可能對修復它沒有興趣。) – molbdnilo

回答

1

第一個警告很清楚:該函數聲明爲返回int,但不返回任何內容。如果曾經被調用過,則會導致程序的未定義行爲(UB)。

對於第二個警告,UB是否會發生與否取決於這兩個條件之間的關係:

  • (rw & fdwatch_type_read) && !(rw & fdwatch_type_accept) && !(orig_state & fdwatch_type_read)
  • fdw_rw(cfd) & fdwatch_type_read && pending_ev->events == fdwatch_type_read

如果第二個暗示的第一個,一切都很好,警告可以安全地被忽略。如果第一個可能是錯誤的而第二個是真的,那麼這種情況將再次調用UB(因爲ret僅在第一個爲真時才被初始化)。


這麼多的分析,結論。

不知道該程序應該做什麼,我們不可能說如何解決這些警告。從技術上講,最stragihtforward解決將是從d2cs_conn_set_addr返回東西,並初始化ret中其他功能的東西

先來看ret

由於涉及ret這兩個條件似乎把-1作爲一個誤差值,良好值東西可能是-1(基本上,它初始化爲錯誤狀態)。

但是,更多地查看代碼會顯示您發佈的兩個條件中的代碼之間的差異。第一個調用WSARecv並將其返回值分配給ret,而第二個調用WSARecv並忽略返回值。因此,它更可能是正確的解決將是第二個這樣的線從

WSARecv(fdw_fd(fdw_fds + idx), &wsaBuf, 1, &dummy1, &dummy2, (LPWSAOVERLAPPED)tmpev, NULL); 

改變

ret = WSARecv(fdw_fd(fdw_fds + idx), &wsaBuf, 1, &dummy1, &dummy2, (LPWSAOVERLAPPED)tmpev, NULL); 

(這順便只是說明了爲什麼這是一個好主意,只是在點聲明變量你需要他們)

而現在d2cs_conn_set_addr

這一個是棘手。如果你想找到合適的返回值,你需要檢查呼叫站點(調用該函數的位置)並查看他們期望的返回值。這是可能的,他們將期待一個成功/失敗的返回值,也許是非零對比0,或0-1,或別的東西。這樣的檢查會告訴你要返回什麼。這可能是成功的代碼,因爲函數不能以任何明顯的方式失敗。使用的ASSERT(c, -1)

當然,除非實際上擴展到

if (!c) return -1; 

或類似的,這將使其失效模式(也表明,正確的返回值可以是0或「什麼比-1其他」或「任何非負面的」)。

因此,除了調用d2cs_conn_set_addr的代碼外,還請檢查ASSERT的定義,以期更好地理解如何解決該問題。


總結:這個代碼是完全錯誤的,而如果錯誤程度設法溜進了,誰知道還有什麼其他的問題在那裏潛伏。你應該避開它,如果可能的話,不要使用它。

如果你堅持了下來,這將需要對潛在的問題非常徹底的檢查。

相關問題