0

Why is snprintf giving different value in second case. Is it because any integer limit. Can you please explain how snprintf works and why the reason for that negative value

#include <stdio.h> #include <string.h> main() { char buff[256]; snprintf(buff,256,"%s %d"," value",1879056981); printf("%s",buff); } 

output: value 1879056981

#include <stdio.h> #include <string.h> main() { char buff[256]; snprintf(buff,256,"%s %d"," value",2415927893); printf("%s",buff); } 

output: value -1879039403

2
  • en.wikipedia.org/wiki/Integer_overflow Commented Nov 28, 2013 at 20:50
  • Use %lu instead. Because, it's for 64bit int! Commented Jan 17, 2019 at 5:21

2 Answers 2

1

It's because the integer 2415927893 can't represented by any integer type on your system and you have signed overflow in your program.

The exact type of integer literal depends on how big the number is. C11 defines that an integer literal can be of int or long int or long long int, depending on which one fits first in that order.

6.4.4.1 Integer constants

The type of an integer constant is the first of the corresponding list in which its value can be represented.

Turn on the compiler warnings.

On my system, gcc warns about it when I compile youre code with:
gcc -std=c11 -Wall -pedantic t.c

t.c:4:1: warning: return type defaults to ‘int’ [enabled by default] t.c: In function ‘main’: t.c:9:4: warning: format ‘%d’ expects argument of type ‘int’, but argument 5 has type ‘long long int’ [-Wformat] t.c:9:4: warning: format ‘%d’ expects argument of type ‘int’, but argument 5 has type ‘long long int’ [-Wformat] 
Sign up to request clarification or add additional context in comments.

3 Comments

Strictly, the type of 2415927893 is a legal and in-range constant of an unsigned type, probably unsigned int, but when printf() interprets it using the %d format, it treats it as a signed int.
@JonathanLeffler C11, 6.4.4.1 says an integer constant without any suffix is int or long or long long (in that order whichever fits first). It considers the unsigned type only if there's a u/U suffix or if it's a hex/octal constant, which is not the case here. (Although I find it strange that unsigned types are considered for octal/hex constants and not for decimal constants, that's what C11 states). The rules are slightly different in C90 in this regard.
No; you're right; it is a signed integer because there's no U suffix, but it is of the type big enough to hold it which is likely to be long long in a 32-bit implementation and long in a 64-bit system other than Windows 64 (where it will be long long again, or some system-specific name equivalent to that).
1

The literal 2415927893 is interpreded as an int. As it is larger than INT_MAX on your machine, you get an overflow.

To avoid this, you may interpret it as an unsigned int:

snprintf(buff,256,"%s %u"," value",2415927893U);

Or as long long:

snprintf(buff,256,"%s %lld"," value",2415927893ll);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.