通用条款-使用-funsigned char“;仍然导致-Wchar下标“;警告

通用条款-使用-funsigned char“;仍然导致-Wchar下标“;警告,c,gcc,C,Gcc,这不是一个关于如何防止这一警告的问题,而是一个关于我收到警告的原因的问题 考虑以下计划: #include <stdlib.h> #include <stdio.h> #include <string.h> int main() { char *str = "Hello World!"; int len = strlen(str); // Yes, a char, bare with me char index = 6;

这不是一个关于如何防止这一警告的问题,而是一个关于我收到警告的原因的问题

考虑以下计划:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main() {
    char *str = "Hello World!";
    int   len = strlen(str);

    // Yes, a char, bare with me
    char index = 6;
    char seek  = 'Z';

    // Reject the string if str[index] != seek
    // Include some bounds checks for safety
    if (index < 0 || index >= len || str[index] != seek) {
        puts("Rejected");

    } else {
        puts("Kept");
    }

    return 0;
}
gcc
似乎意识到
index<0
将始终为false,因为
index
未签名。这解释了第一个警告。
然而,它仍然会对
str[index]
发出警告,即使它知道
index
永远不会是负数


为什么
gcc
在已经知道字符索引永远不能为负时仍会发出有关字符索引的警告?

-Wchar下标
旨在作为可移植性警告。它告诉您,在一般情况下,
char
可以签名。它在您的案例中未签名这一事实与此无关。如果您不关心一般情况,请禁用警告

$ gcc -Wall -Wextra -funsigned-char char.c -o char
char.c: In function ‘main’:
char.c:15:15: warning: comparison is always false due to limited range of data type [-Wtype-limits]
     if (index < 0 || index >= len || str[index] != seek) {
               ^
char.c:15:5: warning: array subscript has type ‘char’ [-Wchar-subscripts]
     if (index < 0 || index >= len || str[index] != seek) {
     ^
例如,请注意,您不会收到
int
下标的警告,即使
int
可以为负数。编译器假设您知道在对下标使用
int
时正在做什么。但是对于
char
它想发出警告


还请注意,如果在代码中显式使用
signed char
作为下标,则警告将消失,即使
signed char
肯定是负数。编译器再次假定您知道自己在做什么。

-Wchar下标
旨在作为可移植性警告。它告诉您,在一般情况下,
char
可以签名。它在您的案例中未签名这一事实与此无关。如果您不关心一般情况,请禁用警告

$ gcc -Wall -Wextra -funsigned-char char.c -o char
char.c: In function ‘main’:
char.c:15:15: warning: comparison is always false due to limited range of data type [-Wtype-limits]
     if (index < 0 || index >= len || str[index] != seek) {
               ^
char.c:15:5: warning: array subscript has type ‘char’ [-Wchar-subscripts]
     if (index < 0 || index >= len || str[index] != seek) {
     ^
例如,请注意,您不会收到
int
下标的警告,即使
int
可以为负数。编译器假设您知道在对下标使用
int
时正在做什么。但是对于
char
它想发出警告


还请注意,如果在代码中显式使用
signed char
作为下标,则警告将消失,即使
signed char
肯定是负数。编译器再次假定您知道自己在做什么。

在当前平台上不能为负值,但在另一个平台上可能为负值。警告在不同平台上保持一致,帮助您编写可移植代码。(我不是说我是否同意)因为这正是
-Wchar下标
的具体指定方式?如果您确定它不是负数,可以使用
带符号字符
并强制转换为
大小
,或者使用
无符号字符
变量并删除当时无用的测试。换言之:不要胡闹症状,而是修复实际故障。它在当前平台上不能是负面的,但在另一个平台上可能是负面的。警告在不同平台上保持一致,帮助您编写可移植代码。(我不是说我是否同意)因为这正是
-Wchar下标
的具体指定方式?如果您确定它不是负数,可以使用
带符号字符
并强制转换为
大小
,或者使用
无符号字符
变量并删除当时无用的测试。换言之:不要在症状上胡闹,而是修复实际的故障。