簡體   English   中英

C 錯誤:非無效 function 不在所有控制路徑中返回值 [-Werror,-Wreturn-type]

[英]C error: non-void function does not return a value in all control paths [-Werror,-Wreturn-type]

我正在編寫 function 以驗證字符串的 strlen 是否 = 26 並返回 boolean 值但是我收到一條錯誤消息,指出“錯誤:非無效 ZC1C425268E68385D14AB507,不返回 aZ 值在所有控制中Wreturn-type]" 盡管沒有辦法不返回值。 (我已經嘗試過使用 else 而不是 else if 並得到相同的錯誤)

bool ValidateLength(string key, int argc)  
{
    if (strlen(key) != 26)
    {
        printf("Usage: ./substitution key\n");
        printf("Key must consist of 26 alphabetic characters.\n");
        return false;
    }
    else if (strlen(key) == 26)
    {
        return true;
    }
}

盡管 GCC 能夠分析代碼並確定執行了其中一種情況(如下面的補充所示),但想必這種分析只發生在編譯過程的后期。 在初始分析期間,代碼名義上包含三個代碼路徑。 我想到了三個可能的原因:

  • 由於編譯器的構造方式,警告通常會提前報告,並且根據以后的分析來抑制此警告將很困難。
  • 報告此警告被認為是有用的,因為它通常是由無意的程序設計導致的,而不是通過冗余測試故意覆蓋所有案例。
  • 忽略了壓制警告的機會。

盡管如此,這很容易解決。 代碼可以重寫為:

bool ValidateLength(string key, int argc)  
{
    if (strlen(key) != 26)
    {
        printf("Usage: ./substitution key\n");
        printf("Key must consist of 26 alphabetic characters.\n");
        return false;
    }
    else
    {
        return true;
    }
}

或者:

bool ValidateLength(string key, int argc)  
{
    if (strlen(key) != 26)
    {
        printf("Usage: ./substitution key\n");
        printf("Key must consist of 26 alphabetic characters.\n");
        return false;
    }
    return true;
}

雖然您報告測試前一個選項,但 GCC 在這種情況下不會報告警告,所以我認為您的測試有問題,例如編譯代碼而不是您嘗試編譯的代碼。

補充

可以說,這是編譯器的一個缺點。 查看GCC 11.2 為此生成的程序集-O3 ,我們看到它實際上已經認識到ifelse if中所有情況的聯合涵蓋了所有可能性:它只生成了兩個代碼路徑,而不是三個。 它調用strlen一次,然后跳轉到.L1或進入“then”代碼,該代碼在.L1處重新加入。 兩條路徑都返回一個值。 所以 GCC 知道沒有可能的控制路徑不返回值,但它仍然報告了警告(提升為錯誤)。

此外,通過將 function 返回類型更改為 int 並將“then”代碼中的返回值更改為0 、“else if”代碼中的1和顯示僅返回 0 或 1 的匯編代碼之外的2進行測試,證明 GCC 是不僅僅是將第三條路徑折疊成“未定義的行為”; 它完全消除了它,因為它是不可能的。

你的塊 if/else if 被過度約束....

你試過這個嗎?

bool ValidateLength(string key, int argc)  
{
    if (strlen(key) == 26)
        return true;

    printf("Usage: ./substitution key\n");
    printf("Key must consist of 26 alphabetic characters.\n");
    return false;
}

盡量避免代碼中出現許多返回語句。 一個就夠了。 它使代碼更不容易出現人為錯誤。

bool ValidateLength(string key, int argc)  
{
    bool result = key ? strlen(key) != 26 : false;
    if (result)
    {
        printf("Usage: ./substitution key\n");
        printf("Key must consist of 26 alphabetic characters.\n");
    }
    return result;
}

在您的代碼中,編譯器不知道在您傳遞指針時調用strlen時是否不會更改key (副作用)。 所以它不知道第二個strlen是否會返回與第一個相同的值。

暫無
暫無

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

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