14

According to http://linux.die.net/man/3/sprintf and http://www.cplusplus.com/reference/cstdio/sprintf/ sprintf() and family return the number of characters written on success. On failure, a negative value is returned. I would assume that an error could occur if the format string is malformed so a negative return value could indicate something other than a malloc() error. Does errno get set to indicate what the error was?

Uyghur Lives Matter
  • 18,820
  • 42
  • 108
  • 144

2 Answers2

11

C++ defers to C and C does not require or mention errno in the description of sprintf() and family (although for certain format specifiers, these functions are defined to call mbrtowc(), which may set EILSEQ in errno)

POSIX requires that errno is set:

If an output error was encountered, these functions shall return a negative value and set errno to indicate the error.

EILSEQ, EINVAL, EBADF, ENOMEM, EOVERFLOW are mentioned explicitly: http://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html

Cubbi
  • 46,567
  • 13
  • 103
  • 169
  • 1
    What does it mean when C/C++ does not require a behavior (e.g. setting `errno` after `sprintf()` failure) but POSIX does? I'm unclear where POSIX fits into the picture - if I wrote C code that called `sprintf()`, I guess I'm calling a libc function...but what determines if I'm getting the POSIX-required behavior or not? – StoneThrow Nov 07 '18 at 01:39
  • 2
    @StoneThrow the OS you're using determines that. If it's a Unix (including MacOS and Linux), POSIX applies. If it's Windows, it's up to the whims of its libc authors. – Cubbi Nov 07 '18 at 14:18
5

I always like the "try it out" method when I have a question like this.

char buffer[50];
int n, localerr = 0;
n = sprintf(buffer, "%s", "hello");
localerr = errno; // ensure printf doesn't mess with the result
printf("%d chars\nerrno: %d\nstrerror:%s\n", n, localerr, strerror(localerr));

> 5 chars
errno: 0
strerror: Success

n = sprintf(buffer, NULL, NULL);
localerr = errno;
printf("%d chars\nerrno: %d\nstrerror:%s\n", n, localerr, strerror(localerr));

> -1 chars
errno: 22
strerror: Invalid argument

Looks like it gets set when compiling with gcc on linux. So that's good data, and in the man page for errno it does mention that printf() (same family as sprintf()) may change errno (in the examples at the bottom).

Patrick Schlüter
  • 11,394
  • 1
  • 43
  • 48
Mike
  • 47,263
  • 29
  • 113
  • 177
  • 2
    Note that the "try it out" method relies on the implementation being standard compliant and the standard not allowing room for different behavior. Sometimes this method can mislead you... – skyking Dec 20 '17 at 15:38