Может ли макрос C #error отображать многострочное сообщение? - PullRequest
0 голосов
/ 18 сентября 2018

Я пытался использовать директиву #error с компилятором GCC следующим образом:

#error "The charging pins aren't differing! One pin cannot be used for multiple purposes!"

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

#error "The charging pins aren't differing! 
    One pin cannot be used for multiple purposes!"

Затем я получил несколько сообщений об ошибке:

warning: missing terminating " character
#error "The charging pins aren't differing! One pin

error: missing terminating " character
cannot be used for multiple purposes!"

Если я вставлю черную черту в конце первой строки, диагностическое сообщение содержит все пробелы между началом второй строки и первым словом (Один). Если обе строки являются строками, диагностическое сообщение показывает внутренние двойные кавычки.

Итак, вопрос: как мне добиться этого результата? (или аналог без двойных кавычек, но с апострофом)

#error "The charging pins aren't differing! One pin cannot be used for multiple purposes!"

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

Как указано здесь

Ни макрос "# error", ни "# warning" не расширяет свой аргумент. Каждая внутренняя последовательность пробелов заменяется одним пробелом. Строка должна состоять из полных токенов .Лучше всего, чтобы аргумент этих директив был одностроковой константой ;это позволяет избежать проблем с апострофами и т. п.

Так что вы можете использовать его только в одной строке.

#include <stdio.h>
//#define var 10
#ifdef var
#error "The charging pins aren't differing! One pin cannot be used for multiple purposes!"
#endif
int main(void){
  printf("in  main() \n");
  return 0;
}
0 голосов
/ 18 сентября 2018

К сожалению, вы не можете иметь все это.

  • Либо вам нужно избавиться от апострофа, чтобы в сообщении содержалось только то, что считается допустимым токеном предварительной обработки.
  • Или вы можете записать его в виде строки на одномline.
  • Или вы можете написать его двумя строковыми литералами и разбить строку на \.Вы не можете сделать это в середине строкового литерала, потому что тогда это не будет действительный токен предварительной обработки.Это будет выглядеть странно, хотя, например: error: "hello" "world".
  • Опора конкатенации двух строк литералов не будет работать, так как директива error будет выглядеть только до тех пор, пока не найдет символ новой строки висточник.И директива error в любом случае преобразует все, что вы вводите в строки.

Соответствующие этапы перевода (из C17 5.1.1.2) выполняются в следующем порядке:

2) Каждыйудаляется экземпляр символа обратной косой черты (), за которым сразу следует символ новой строки, объединяя физические исходные строки для формирования логических исходных строк.

3) Исходный файл разлагается на токены предварительной обработки и последовательности пробеловсимволы (включая комментарии).

4) Директивы предварительной обработки выполняются, ...

6) Литеральные токены смежных строк объединяются.

#error isвыполняется на шаге 4, раньше, чем конкатенация строковых литералов на шаге 6.

Лично я считаю, что лучшим решением будет пропустить апостроф:

#error The charging pins are not differing! \
       One pin cannot be used for multiple purposes!

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

...