Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to suppress sprintf() warning 'directive writing between 1 and 11 bytes into a region of size 6 '

Tags:

c

I am using sprintf() to create a string, literal is an integer.

char tag[16];
sprintf(tag, "Literal - %d", literal); 

But the project make is considering all warnings as error and raising error:

error: ‘%d’ directive writing between 1 and 11 bytes into a region of size 6 [-Werror=format-overflow=]  
   sprintf(tag, "Literal - %d", literal);    //snprintf(tag, 16, "Literal - %d", literal);  
           ^~   
apps/ziptest/test_literals_lzma.c:42:15: note: directive argument in the range [-2147483648, 255]   sprintf(tag, "Literal - %d", literal);    //snprintf(tag, 16, "Literal
    - %d", literal);  
                   ^~~~~~~~~~~~~~   
apps/ziptest/test_literals_lzma.c:42:2: note: ‘sprintf’ output between 12 and 22 bytes into a destination of size 16   sprintf(tag, "Literal - %d", literal);    //snprintf(tag, 16, "Literal - %d", literal);     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   
cc1: all warnings being treated as errors Makefile:370: recipe for target 

can this warning be avoided? (literal range is from 0 to 255)

like image 508
Aamir Shaikh Avatar asked Aug 05 '18 19:08

Aamir Shaikh


1 Answers

with

sprintf(tag, "Literal - %d", literal); 

since your buffer is 16 bytes, and the prefix is 10 bytes, that leaves 5 bytes to write the string representation of literal.

Since int is probably 32 bit on your system, it ranges up to 2147483647 and negative-wise -2147483648 (11 characters), the compiler warns you (since it was able to compute all the sizes)

Now since you know that the range cannot be outside 0-255, just reduce literal size by, for instance, declaring it as unsigned short (short can be 6 bytes long as a string: -32768 as chux noted in comments) so you have leeway for your value.

unsigned short literal = 123;
sprintf(tag, "Literal - %hu", literal); 

(you could use unsigned char which ranges exactly from 0 to 255, using %hhu format specifier)

or just cast when printing:

sprintf(tag, "Literal - %hu", (unsigned short)literal); 

(%u probably works too, but depends on how smart the compiler is: is it analysing just the format or the size of variable args?)

Let's not forget the most obvious solution now that we know why the warning occurs: let's define the array with a large enough size.

char tag[25];  // 21 would have been okay

should do it. Shaving it too close isn't generally a good idea, unless you're running out of ressources.

like image 164
Jean-François Fabre Avatar answered Oct 06 '22 22:10

Jean-François Fabre