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.

The code is GCC (or Clang) specific.  I doubt it's doable (with the same level of safety and clarity) in standard C, although a standard solution would be nice.

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:

```c
/*
 * int	alx_sbprintf(char buff[restrict], int *restrict written,
 *				const char *restrict format, ...);
 */
#define alx_sbprintf(buff, written, format, ...)		(				\
{																		\
		int		len_;													\
		int		err_;													\
																		\
		alx_static_assert_array(buff);									\
		err_	= 0;													\
																		\
		len_	= snprintf(buff, sizeof(buff), format, ##__VA_ARGS__);	\
		if (written != NULL)											\
				*written = len_;										\
																		\
		if (len_ < 0) {													\
				err_	= -errno;										\
				goto ret_;												\
		}																\
		if ((uintmax_t)len_ >= sizeof(buff)) {							\
				errno	= ENOMEM;										\
				err_	= ENOMEM;										\
				goto ret_;												\
		}																\
ret_:																	\
		err_;															\
}																		\
)
```

  [1]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/snprintf.html