This is the code that **Toby Speight** suggested in his answer:

```c
/*
 * int	sbprintf(char buff[restrict], int *restrict written,
 *								const char *restrict format, ...);
 */
#define sbprintf(buff, written, format, ...)	(						\
{																		\
		int		len_;													\
																		\
		alx_static_assert_array(buff);									\
																		\
		len_	= snprintf((buff), sizeof(buff), format, ##__VA_ARGS__);\
		if (written != NULL)											\
				*written = len_;										\
		len_ >= (int)sizeof(buff);										\
}																		\
)
```

_________________________________________________

I have tested it and works as expected:

 - If `written` is `NULL` it doesn't write into it.
 - The return value is `true` when the string is truncated and `false` otherwise.
 - It doesn't compile if `buff` is not an array.
 - It accepts a variable number of arguments after `format`, including no arguments.

The comment above the macro is the prototype that a user should see, to better understand the usage, although a real function with that prototype wouldn't work because of the array decaying to a pointer.

____________________________________

Comments about the style:

I tried to follow the Linux Kernel Coding Style, but there have been exceptions:

`if (written != NULL)` is used instead of `if (written)` to avoid the compiler complaining:

```
main.c:22:23: error: the address of ‘w1’ will always evaluate as ‘true’ [-Werror=address]
  if (alx_sbprintf(b1, &w1, test))
                       ^
.../libalx/base/stdio/sbprintf.h:36:6: note: in definition of macro ‘alx_sbprintf’
  if (written)       \
      ^~~~~~~
```

_____________

**EDIT:**

Given that `snprintf` sets `errno` (at least in [POSIX][1]), it would be good to set `errno` to `ENOMEM` on truncation.

__________________________________________


**EDIT:**

This version includes the improvements suggested by **Toby Speight** and  **chux**, as well as setting `errno` on error.  First I added code to the macro, but it proved to have [some problems][2] (at least it didn't compile, so no dangerous bugs).  Now it's an `extern` function enclosed in a simple macro.

Now the code relies less on GCC extensions.

Properties:

 - If `written` is `NULL` it doesn't write into it.
 - It doesn't compile if `buff` is not an array.
 - It accepts a variable number of arguments after `format`, including no arguments.
 - Sets `errno` on any error.
 - If there's a `snprintf` internal error, the error code is negative (`-errno`), and `written` is also negative.
 - If the string is truncated, the error code is positive (`ENOMEM`).
 - If the error code is negative, the string should not be trusted;  if it's positive, it's been truncated, but it's a valid string.

Code:

`sbprintf.h`:
```c
#ifndef ALX_STDIO_PRINTF_SBPRINTF_H
#define ALX_STDIO_PRINTF_SBPRINTF_H


#include <stddef.h>

#include "libalx/base/assert/assert.h"


/*
 * int	sbprintf(char buff[restrict], int *restrict written,
 *				const char *restrict format, ...);
 */
#define sbprintf(buff, written, fmt, ...)	(							\
{																		\
																		\
		alx_static_assert_array(buff);									\
		sbprintf__(buff, written, sizeof(buff), fmt, ##__VA_ARGS__);	\
}																		\
)


int		sbprintf__(char buff[restrict], int *written, size_t nmemb,
						char *restrict format, ...);


#endif		/* libalx/base/stdio/printf/sbprintf.h */
```

`sbprintf.c`:
```c
#include "libalx/base/stdio/printf/sbprintf.h"

#include <errno.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>


int		sbprintf__(char buff[restrict], int *written, size_t nmemb,
						char *restrict format, ...)
{
		va_list	ap;
		int	len;

		va_start(ap, format);
		len		= vsnprintf(buff, nmemb, format, ap);
		va_end(ap);

		if (written != NULL)
				*written = len;

		if (len < 0)
				goto err;
		if ((unsigned)len >= nmemb)
				goto trunc;

		return	0;
err:
		return	-errno;
trunc:
		if (written)
				*written = nmemb - 1;
		errno	= ENOMEM;
		return	ENOMEM;
}
```




  [1]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/snprintf.html
  [2]: https://stackoverflow.com/q/56825271/6872717