简体   繁体   English

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

[英]Warning C4715: 'd2cs_conn_set_addr' : not all control paths return a value

I'm having some issues compiling a C++ build: I'm getting two warnings from the compiler.我在编译 C++ 版本时遇到了一些问题:我收到了来自编译器的两个警告。

connection.c(813): warning C4715: 'd2cs_conn_set_addr' : not all control paths return a value connection.c(813):警告 C4715:“d2cs_conn_set_addr”:并非所有控制路径都返回值

This where the code points me:这是代码指向我的地方:

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

fdwatch_iocp.c(246): warning C4700: uninitialized local variable 'ret' used fdwatch_iocp.c(246):警告 C4700:使用了未初始化的局部变量“ret”

Points to this piece:这篇文章的要点:

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

I didn't code this, I'm just trying to compile with no errors.我没有编码这个,我只是试图编译没有错误。

The first warning is clear: the function is declared to return an int , but doesn't return anything.第一个警告很明确:该函数被声明为返回一个int ,但不返回任何内容。 If it's ever called, it will cause Undefined Behaviour (UB) of the program.如果它被调用过,它将导致程序的未定义行为(UB)。

For the second warning, whether UB will happen or not depends on the relationship between these two conditions:对于第二个警告,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

If the second one implies the first one, all is well and the warning can safely be ignored.如果第二个暗示第一个,那么一切都很好,可以安全地忽略警告。 If it's ever possible for the first one to be false and the second one to be true, such a case will again invoke UB (since ret is only initialised if the first one is true).如果第一个为假而第二个为真,这种情况将再次调用 UB(因为ret仅在第一个为真时才初始化)。


So much for analysis, on to conclusions.分析到此为止,最后得出结论。

Without understanding what the program is supposed to do, it is impossible for us to say how to fix these warnings.在不了解程序应该做什么的情况下,我们不可能说出如何修复这些警告。 Technically, the most stragihtforward fix would be to return something 1 from d2cs_conn_set_addr , and to initialise ret to something 2 in the other function.从技术上讲,最直接的解决方法是从d2cs_conn_set_addr返回1 d2cs_conn_set_addr ,并在另一个函数中将ret初始化为2值。

Let's look at ret first.我们先来看看ret

Since both conditions involving ret seem to treat -1 as an error value, a good value for something 2 could be -1 (basically, initialise it to an error state).由于涉及ret两个条件似乎都将-1视为错误值,因此2 的合适值可能是-1 (基本上,将其初始化为错误状态)。

However, looking at the code a bit more shows a discrepancy between the code in the two conditions you've posted.但是,多看一下代码会发现您发布的两种情况下的代码之间存在差异。 The top one calls WSARecv and assigns its return value to ret , while the second one simply calls WSARecv and ignores the return value.第一个调用WSARecv并将其返回值分配给ret ,而第二个调用WSARecv并忽略返回值。 Therefore, it's more likely that the proper fix would be to change the second such line from因此,更可能的正确解决方法是将第二条这样的行从

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

to

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

(This incidentally just shows why it's a good idea to only declare variables at the point where you need them) (顺便说一句,这只是说明为什么只在需要变量的地方声明变量是个好主意)

And now for d2cs_conn_set_addr .现在是d2cs_conn_set_addr

This one is trickier.这个比较棘手。 If you want to find a suitable return value, you'll need to inspect the call sites (where that function is called) and see what return values they expect.如果您想找到合适的返回值,您需要检查调用站点(调用该函数的位置)并查看它们期望的返回值。 It's possible they will expect a success/failure return value, perhaps non-zero vs. 0 , or 0 vs. -1 , or something else.他们可能会期望成功/失败返回值,可能是非零与0 ,或0-1 ,或其他。 Such inspection would then tell you what to return.这样的检查会告诉你要返回什么。 That would probably be the success code, since the function cannot fail in any obvious ways.那可能是成功代码,因为该函数不会以任何明显的方式失败。

Unless of course that use of ASSERT(c, -1) actually expands to当然,除非ASSERT(c, -1)实际上扩展到

if (!c) return -1;

or similar, which would give it a failure mode (and also suggest that the correct return value could be 0 or "anything other than -1 " or "anything non-negative").或类似的,这会给它一个失败模式(并且还表明正确的返回值可能是0或“任何非-1 ”或“任何非负值”)。

So, in addition to the code which calls d2cs_conn_set_addr , also check the definition of ASSERT to hopefully better understand how to fix it.因此,除了调用d2cs_conn_set_addr的代码d2cs_conn_set_addr ,还要检查ASSERT的定义,以期更好地了解如何修复它。


To summarise: this code is plain wrong, and if errors of this degree managed to slip into it, who knows what other problems lurk in there.总结一下:这段代码显然是错误的,如果这种程度的错误设法进入其中,谁知道那里还潜伏着什么其他问题。 You should steer clear of it and not use it if that's at all possible.如果可能的话,你应该避开它,不要使用它。

If you're stuck with it, it will require very thorough inspection for potential issues.如果您坚持使用它,则需要对潜在问题进行非常彻底的检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM