Вы могли бы сделать макрос
#define STR2(STR) (int const){ (STR).l }, (char const*const){ (STR).s }
и затем используйте это как printf("%.*s\n", STR2(str))
.
Помните, что это оценивает STR
дважды, так что будьте осторожны с побочными эффектами, но вы, вероятно, уже знали об этом.
Edit:
Я использую составные инициализаторы, так что это неявные преобразования. Если что-то пойдет не так, больше шансов, что компилятор предупредит вас, чем при явном приведении.
Например, если STR
имеет поле .l
, являющееся указателем, и вы бы поместили приведение только к int
, все компиляторы с радостью преобразуют этот указатель в int
. Аналогично для поля .s
это действительно должно соответствовать char*
или чему-то совместимому, в противном случае вы увидите предупреждение или ошибку.