Макрос Stringification всегда добавляет один пробел

Учитывая следующий код, который печатает строку, которая представляет собой преобразование двух слов:

#define PORT_INFO_MAC_2(portNum)   port:     portNum

#define PORT_INFO_MAC(portNum) PORT_INFO_MAC_2(portNum)

/* Stringify macro expansion instead of the macro itself */
#define INVOKE_MACRO(...) #__VA_ARGS__

printf(" %s " , INVOKE_MACRO(PORT_INFO_MAC(1)) ); /* In a more general way, I'll be using it like follows: INVOKE_MACRO(PORT_INFO_MAC(2), PORT_INFO_MAC(1), ...) */

Вывод всегда " port: 1 " с одним пробелом между "port" и "1". Почему там всегда есть одно пространство и есть ли способ контролировать количество пробелов?

изменение количества пробелов в макросе PORT_INFO_MAC_2 между port и portNum не меняет количество выходного пространства.

РЕДАКТИРОВАТЬ
Кажется, что есть два случая, в первом случае port и portNum являются ближайшими - PORT_INFO_MAC_2(portNum) port:portNum, тогда между ними нет пробела в выводе. Во втором случае, когда в макросе между ними существует любое количество пробелов, количество пробелов в выводе всегда равно 1. Есть ли этому какое-то формальное объяснение? Есть ли какой-то контроль над этим?


person user2162550    schedule 21.09.2016    source источник
comment
Примечание: пробел — это большая кнопка на клавиатуре, которая генерирует символы пробел.   -  person too honest for this site    schedule 21.09.2016


Ответы (1)


Почему там всегда есть одно пространство и есть ли способ контролировать количество пробелов?

Потому что это именно то, для чего предназначен оператор строковой обработки:

Если в списке замещения параметру непосредственно предшествует токен предварительной обработки #, оба они заменяются токеном предварительной обработки с литералом из одной символьной строки, который содержит написание последовательности токенов предварительной обработки для соответствующего аргумента. Каждое появление пробела между токенами предварительной обработки аргумента становится одиночным символом пробела в литерале строки символов.

(C2011 6.10.3.2/2; курсив добавлен)

Конечно, если между токенами предварительной обработки вообще нет пробелов, то они не появляются в строке.

person John Bollinger    schedule 21.09.2016
comment
Точно. Можете дать ссылку на исходный документ? - person user2162550; 21.09.2016
comment
@user2162550, обычно я ссылаюсь на версию документа в формате PDF Проект N1570. Мой ответ содержит номера разделов и абзацев. Вы можете найти другие версии, включая представления в формате HTML, в Google для n1570. Окончательный стандартный документ недоступен бесплатно, но имеет лишь тривиальные отличия от N1570. - person John Bollinger; 21.09.2016