簡體   English   中英

對理解和消除 -Wsign-compare gcc 的警告感到困惑

[英]Confused about understanding and silencing a -Wsign-compare gcc's warning

這是我正在嘗試編譯的函數:

static ssize_t  output(t_out_buffer *buf, char const *src, size_t size)
{
        size_t  osize;

        osize = size;
        while ((size > 0)
               && (size -= write(buf->fd, src, size) < osize))
        {
                src += osize - size;
                buf->count +=  osize - size;
                osize = size;
        }
        if (osize < size)
                return (T_OUT_BUFFER_ERROR);
        else
                return (buf->count);
}

和 gcc 的抱怨:

t_out_buffer.c:11:42: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    && (size -= write(buf->fd, src, size) < osize))
                                          ^

我認為因為size是無符號的,所以size -= whateverintiwant osize將是無符號的,因為osize也是無符號的。 我現在假設我錯了,但我真的不明白為什么。 此外,你能給我一些提示讓我保持沉默嗎?

這個表達並沒有像你想象的那樣:

(size -= write(buf->fd, src, size) < osize)

小於運算符<優先級高於復合賦值運算符-= 所以上面的解析為:

(size -= (write(buf->fd, src, size) < osize))

因此,這將ssize_t類型的write輸出與size_t類型的ssize_t進行osize 這是有符號/無符號比較發生的地方。 這個比較的結果然后從size減去,所以它一次只會減少 1。

在作業周圍添加括號:

((size -= write(buf->fd, src, size)) < osize)

當您現在將size_tsize_t進行比較時,警告將消失。

然而,還有另一個問題。 如果write返回 -1,那么您將減去該值,即如果失敗則加 1。

您應該重構,以便在循環內進行讀取,並且僅在成功時才添加結果。

    while (size > 0) {
    {
            ssize_t rval = write(buf->fd, src, size);
            if (rval == -1) {
                return T_OUT_BUFFER_ERROR;
            }
            size -= rval;
            src += rval;
            buf->count +=  rval;
    }

我認為您有運算符優先級問題。 您的代碼被解釋為:

&& (size -= (write(buf->fd, src, size) < osize)))

因此,您可以通過強制所需的優先級來修復它:

&& ((size -= write(buf->fd, src, size)) < osize))

警告通過指出問題來幫助您,如果您不完全理解警告,則永遠不應該使警告靜音。
此外,在條件內使用副作用是不好的做法。 如果您將賦值運算符-=移到條件之外,您的代碼將更容易理解和維護。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM