开发者

conversion to ‘size_t’ from ‘int’ may change the sign of the result - GCC , C

In my project I have turned on treat warnings as errors and compiling using the -pedantic and -ansi tags. I am using GCC compiler. In this开发者_JAVA技巧 project I have to use a third party source code which has got lot of warnings. Since I treat warnings as errors, I am having a tough time in fixing their code.

Most of the warnings are about invalid conversion from int to size_t or viceversa. In some cases, I won't be able to make both the variables same type, I mean I won't be able to change something to size_t. In such cases I am doing an explicit cast. Something like,

size_t a = (size_t) atoi(val);

I am wondering is this the correct approach? Is there any problem in doing cast like this?

If these warnings are minor, can I suppress it only on their files? How do I do the same on MSVC?


Edit:

Casting is the only approach if you want to shut up the compiler per instance in a portable way. It is fine as long as you know what you're doing, e.g. that you can ensure the result of atoi will never be negative.

In GCC, you can turn off all sign conversion warnings with the -Wno-sign-conversion flag. There is also -Wno-sign-compare (for stuff like 2u > 1) but it won't be relevant unless you use -Wextra.

You could also use the diagnostic pragmas like

#pragma GCC diagnostic ignored "-Wsign-conversion"

In MSVC, there are several warnings relevant to signed/unsigned mismatch, e.g.:

  • Level 4:
    • C4389, C4245, C4365
  • Level 3:
    • C4018 (2u > 1)
  • Level 2:
    • C4267 (size_tint)

To disable a warning in MSVC, you could add a #pragma warning e.g.

#pragma warning (disable : 4267)

or add a /wd4267 flag in the compiler options.


Perhaps you should use strtoul instead of atoi.

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

(There is no warning only if size_t is as large as unsigned long. On most platforms, this is true, but it is not guaranteed.)

The advantage is you could perform error checking with this function, e.g.

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


Have a look at the OpenOffice wiki on the best practices for error-free code: http://wiki.services.openoffice.org/wiki/Writing_warning-free_code

They suggest static casts for these conversions, and then supply a pragma to disable warnings for a particular section of code.


I personally consider this kind of warning idiotic and would turn it off, but the fact that you're asking about it suggests that you might be sufficiently unfamiliar with conversions between integer types and the differences in signed and unsigned behavior that the warning could be useful to you.

Back on the other hand again, I really despise [explicit] casts. The suggestion to use strtoul instead of atoi is probably a very good one. I see you commented that atoi was only an example, but the same principle applies in general: use functions that return the type you want rather than forcing a different type into the type you want. If the function is one you wrote yourself rather than a library function, this may just mean fixing your functions to return size_t for sizes rather than int.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜