从'int'转换为'size_t'可能会改变结果的符号 - GCC,C

时间:2010-07-31 06:44:33

标签: c visual-c++ gcc warnings

在我的项目中,我已将警告视为错误,并使用-pedantic-ansi标记进行编译。我正在使用GCC编译器。在这个项目中,我必须使用第三方源代码,它有很多警告。由于我将警告视为错误,因此我在修复代码时遇到了困难。

大多数警告都是关于从intsize_t的无效转换或反之亦然。在某些情况下,我将无法使两个变量都相同,我的意思是我将无法将某些内容更改为size_t。在这种情况下,我正在做一个明确的演员。像,

size_t a = (size_t) atoi(val);

我想知道这是正确的做法吗?像这样做演员有什么问题吗?

如果这些警告很轻微,我可以仅对其文件进行压制吗?我如何在MSVC上做同样的事情?

3 个答案:

答案 0 :(得分:7)

编辑:

如果要以可移植的方式关闭每个实例的编译器,则转换是唯一的方法。只要您知道自己在做什么,就可以了。您可以确保atoi的结果永远不会消极。

在GCC中,您可以使用-Wno-sign-conversion标记关闭所有符号转换警告。还有-Wno-sign-compare(适用于2u > 1之类的内容),但除非您使用-Wextra,否则它不相关。

您也可以使用diagnostic pragmas之类的

#pragma GCC diagnostic ignored "-Wsign-conversion"

在MSVC中,有几个警告与签名/无符号不匹配有关,例如:

要在MSVC中禁用警告,您可以添加#pragma warning,例如

#pragma warning (disable : 4267)

或在编译器选项中添加/wd4267标志。


也许您应该使用strtoul代替atoi

size_t a = strtoul(val, NULL, 0);

(仅当 size_tunsigned long一样大时才会出现警告。在大多数平台上,这是真的,但不能保证。)

优点是您可以使用此功能执行错误检查,例如

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

int main () {
    char val[256];
    fgets(val, 256, stdin);
    char* endptr;
    size_t a = strtoul(val, &endptr, 0);
    if (val == endptr) {
        printf("Not a number\n");
    } else {
        printf("The value is %zu\n", a);
    }
    return 0;
}

答案 1 :(得分:4)

请查看OpenOffice wiki,了解无错代码的最佳做法:http://wiki.services.openoffice.org/wiki/Writing_warning-free_code

他们为这些转换建议静态强制转换,然后提供一个pragma来禁用特定代码段的警告。

答案 2 :(得分:-2)

我个人认为这种警告是愚蠢的,并且会将其关闭,但事实上你问这个事实表明你可能对整数类型之间的转换以及警告的签名和未签名行为的差异非常不熟悉对你有用。

再次回到另一方面,我真的鄙视[明确]演员。使用strtoul代替atoi的建议可能非常好。我看到你评论atoi只是一个例子,但同样的原则一般适用:使用返回所需类型的函数,而不是强制使用不同类型的函数。如果函数是您自己编写的函数而不是库函数,则可能只是意味着修复函数以返回size_t的大小而不是int