Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 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?

like image 203
Navaneeth K N Avatar asked Jul 31 '10 06:07

Navaneeth K N


People also ask

Why is Size_t unsigned?

size_t is unsigned because negative sizes make no sense.

When should I use Size_t in C?

size_t is commonly used for array indexing and loop counting. Programs that use other types, such as unsigned int, for array indexing may fail on, e.g. 64-bit systems when the index exceeds UINT_MAX or if it relies on 32-bit modular arithmetic.

Does Size_t exist in C?

Master C and Embedded C Programming- Learn as you goThe datatype size_t is unsigned integral type. It represents the size of any object in bytes and returned by sizeof operator. It is used for array indexing and counting.

Can Size_t be a double?

Converting to double will not cause an overflow, but it could result in a loss of precision for a very large size_t value. Again, it doesn't make a lot of sense to convert a size_t to a double ; you're still better off keeping the value in a size_t variable.


2 Answers

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;
}
like image 91
kennytm Avatar answered Oct 18 '22 00:10

kennytm


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.

like image 32
Mahmoud Al-Qudsi Avatar answered Oct 18 '22 01:10

Mahmoud Al-Qudsi