Как сделать G ++, препроцессор произвел новую строку в макросе?

Есть ли путь в gcc/g ++ 4.* для записи макроса, который расширяется в несколько строк?

Следующий код:

#define A X \ Y

Расширяется в

X Y

Мне нужен макрос, расширяющийся в

X
Y
29
задан Brian Tompsett - 汤莱恩 10 June 2016 в 07:55
поделиться

5 ответов

Основная идея состоит в том, что каждый процесс является функциональной программой над входным потоком сообщений. Результатом функциональной программы является выходной поток сообщений другим пользователям. С этой точки зрения эрланг - довольно чистый функциональный язык; нет разрушительных обновлений структур данных (например, setcar в Lisp и большинстве схем).

За редким исключением, все встроенные функции, такие как операции с таблицами ETS, также следуют этой модели: помимо проблем эффективности, эти BIF могли быть фактически реализованы с чистыми процессами Erlang и передачей сообщений.

Так что да, язык Erlang является функциональным, но набор взаимодействующих процессов Erlang - это другая вещь. Каждый процесс является текущим вычислением, и как таковой он имеет текущее состояние, которое может изменяться по отношению к другим процессам. Даже база данных - это еще один процесс в этом отношении.

На мой взгляд, это одна из самых важных вещей в Эрланге: вне процесса может быть буря, но внутри, все спокойно, позволяя сосредоточиться на том, что должен делать этот процесс - и только это.

-121--1642851-

В качестве побочного комментария существуют лучшие способы проверки размера массива (для случаев, когда массив находится в области действия и не распался на указатель), которые являются текстовыми:

// simple: runtime result
template <typename T, std::size_t N>
inline std::size_t sizeof_array( T (&)[N] ) {
   return N;
}

// complex: compile time constant
template <typename T, std::size_t N>
char (&static_sizeof_array( T(&)[N] ))[N];   // declared, not defined
#defined SIZEOF_ARRAY( x ) sizeof(static_sizeof_array(x))

В обоих случаях компилятор обнаружит попытку передачи указателя (динамического массива или затухшего массива):

void f( int array[] ) { // really: void f( int *array )
{
//   sizeof_array(array);              // compile time error
//   int another[SIZEOF_ARRAY(array)]; // compile time error
}
int main() {
   int array[] = { 1, 2, 3 };
   std::cout << sizeof_array(array) << std::endl; // prints 3
   int another_array[ SIZEOF_ARRAY(array) ];
   std::cout << sizeof_array(another_array) << std::endl; // 3 again
}
-121--2793595-

Я почти уверен, что CPP, разработанный для C, который не заботится о новых линиях, и все, не может справиться с таким видом работы. Тем не менее, вы можете отметить нужные новые строки какой-то специальной маркерной строкой и передать результат через sed или awk , чтобы получить то, что вы хотите.

2
ответ дан 28 November 2019 в 01:52
поделиться

Из docs :

в настоящей реализации все раскрытие выводится в одной строке

2
ответ дан 28 November 2019 в 01:52
поделиться

Почему имеет значение интервал?

Программа imake, используемая в (более старых?) Сборках X11, использовала препроцессор C для генерации make-файлов, но Программа imake использовала особую технику обозначения концов строк символами @@ на концах строк, а затем пост-обработала вывод препроцессора, чтобы заменить символы @@ на новые строки.

Исходя из этой схемы, я прихожу к выводу, что не существует надежного способа получения новой строки из расширенных макросов в C (или C ++). Действительно, в C нет необходимости, поскольку:

  • C не заботится о новых строках по сравнению с пробелами после запуска препроцессора C, и
  • Вы не можете генерировать директивы препроцессора из макросов и т. Д.
1
ответ дан 28 November 2019 в 01:52
поделиться

Это то, что вы хотите:

#define A "X \nY"
-4
ответ дан 28 November 2019 в 01:52
поделиться

Понятно!

#define anlb /*
*/ A /*
*/ B

anlb anlb

Down arrow

gcc -E -CC nl.c

Down arrow

/*
*/ A /*
*/ B /*
*/ A /*
*/ B
22
ответ дан 28 November 2019 в 01:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: