Вот ошибка, с которой я столкнулся при обновлении до новой версии компилятора:
Ненужное использование оператора вставки токена (##
) непереносимо и может генерировать нежелательные пробелы, предупреждения или ошибки.
Когда результат оператора вставки токена не является допустимым токеном препроцессора, оператор вставки токена является ненужным и, возможно, вредным.
Например, можно попытаться построить строковые литералы во время компиляции, используя оператор вставки токена:
#define STRINGIFY(x) #x
#define PLUS(a, b) STRINGIFY(a##+##b)
#define NS(a, b) STRINGIFY(a##::##b)
printf("%s %s\n", PLUS(1,2), NS(std,vector));
На некоторых компиляторах это выдаст ожидаемый результат:
1+2 std::vector
В других компиляторах это будет включать нежелательные пробелы:
1 + 2 std :: vector
Довольно современные версии GCC (> = 3.3 или около того) не смогут скомпилировать этот код:
foo.cpp:16:1: pasting "1" and "+" does not give a valid preprocessing token
foo.cpp:16:1: pasting "+" and "2" does not give a valid preprocessing token
foo.cpp:16:1: pasting "std" and "::" does not give a valid preprocessing token
foo.cpp:16:1: pasting "::" and "vector" does not give a valid preprocessing token
Решение состоит в том, чтобы опустить оператор вставки токенов при объединении токенов препроцессора в операторы C / C ++:
#define STRINGIFY(x) #x
#define PLUS(a, b) STRINGIFY(a+b)
#define NS(a, b) STRINGIFY(a::b)
printf("%s %s\n", PLUS(1,2), NS(std,vector));
Глава документации GCC CPP о конкатенации содержит более полезную информацию об операторе вставки токенов.