警告C4715:' d2cs_conn_set_addr' :并非所有控制路径都返回值

时间:2016-09-22 08:26:05

标签: c++

我在编译C ++版本时遇到了一些问题:我从编译器那里得到了两个警告。

  

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

我没有对此进行编码,我只是尝试编译而没有错误。

1 个答案:

答案 0 :(得分: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仅在第一个为真时初始化)。

分析,得出结论。

如果不了解该计划应该做什么,我们就不可能说出如何修复这些警告。从技术上讲,最直接的解决方法是从d2cs_conn_set_addr返回某事 1 ,并将ret初始化为某事 2 在另一个函数中。

让我们先看看ret

由于涉及ret的两个条件似乎都将-1视为错误值,因此 2 的一个好值可能是{{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_addr00或其他内容不为零。这样的检查会告诉你要返回什么。这可能是成功代码,因为函数不会以任何明显的方式失败。

除非使用-1实际上扩展到

ASSERT(c, -1)

或类似的,会给它一个失败模式(并且还建议正确的返回值可以是if (!c) return -1; 或“0以外的任何东西”或“任何非负面的东西”。 / p>

因此,除了调用-1的代码之外,还要检查d2cs_conn_set_addr的定义,以便更好地了解如何修复它。

总结一下:这段代码是完全错误的,如果这个学位的错误设法落入其中,谁知道其他潜在的问题。如果可能的话,你应该避开它而不要使用它。

如果您坚持使用它,则需要对潜在问题进行彻底检查。