Расположение с отступом #defines

Вы можете напрямую переслать письмо, используя GmailMessage.forward

message.forward("recipient@example.com,recipient1@example.com");

95
задан Thom Wiggers 26 July 2015 в 22:39
поделиться

8 ответов

Препроцессор Pre-ANSI C не допускал пробела между началом строки и символом "#"; ведущий "#" должен был всегда быть помещен в первый столбец.

Компиляторы пре-ANSI C в наши дни отсутствуют. Используйте любой стиль (пробел перед "#" или пробел между "#" и идентификатором), который вы предпочитаете.

http://www.delorie.com/gnu/docs/gcc/cpp_48.html

99
ответ дан 24 November 2019 в 05:51
поделиться

Что касается синтаксического анализа директив препроцессора, стандарт C99 (и стандарт C89 до него) были ясны относительно последовательности операций, выполняемых компилятором логически. В частности, я считаю, что это означает, что этот код:

/* */ # /* */ include /* */ <stdio.h> /* */

эквивалентен:

#include <stdio.h>

К лучшему или к худшему, GCC 3.4.4 с '-std = c89 -pedantic' принимает строку с комментариями, во всяком случае. Я не защищаю это как стиль - ни на секунду (это ужасно). Я просто думаю, что это возможно.

ISO / IEC 9899: 1999, раздел 5.1.1.2. Этапы перевода гласят:

  1. [Отображение символов, включая триграфы]

  2. [Объединение строк - удаление новой строки с обратной косой чертой]

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

  4. Директивы предварительной обработки выполняются, вызовы макросов расширяются, [...]

Раздел 6.10 Директивы предварительной обработки говорит:

Директива предварительной обработки состоит из последовательности токенов предварительной обработки, которая начинается с участием # токен предварительной обработки, который (в начале фазы перевода 4) является либо первым символом в исходном файле (необязательно после пробела, не содержащего символов новой строки) или следует за пробелом, содержащим как минимум один символ новой строки, и заканчивается следующим символ новой строки.

Единственный возможный спор - это выражение в скобках «(в начале фазы перевода 4)», которое может означать, что комментарии перед хешем должны отсутствовать, поскольку они не заменяются пробелами до тех пор, пока конец фазы 4.

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

Следует отметить, что удаление обратной косой черты и новой строки происходит до анализа комментариев. Следовательно, вы не должны заканчивать комментарии // обратной косой чертой.

16
ответ дан 24 November 2019 в 05:51
поделиться

Я не знаю, почему это не так часто встречается. Конечно, бывают моменты, когда мне нравится вставлять директивы препроцессора.

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

7
ответ дан 24 November 2019 в 05:51
поделиться

Сейчас я считаю, что это в основном выбор стиля. Я думаю, что в какой-то момент в далеком прошлом не все компиляторы поддерживали идею определения отступа препроцессора. Я провел некоторое исследование и не смог подтвердить это утверждение. Но в любом случае, похоже, что все современные компиляторы поддерживают идею отступа макроса препроцессора. У меня нет копии стандарта C или C ++, хотя я не знаю, является ли это стандартным поведением или нет.

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

#if COND1
void foo() {
  #if COND2
  int i;
    #if COND3
  i = someFunction()
  cout << i << eol;
    #endif
  #endif
}
#endif
5
ответ дан 24 November 2019 в 05:51
поделиться

Для приведенного вами примера может оказаться целесообразным использовать отступы, чтобы сделать его более понятным, учитывая, что у вас такая сложная структура вложенных директив.

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

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

3
ответ дан 24 November 2019 в 05:51
поделиться

В данный момент я работаю над некоторым кодом, который содержит ужасную смесь #defines, #ifdefs, #elses, #endifs, #etc. Все это часто смешивается с нормальным C-кодом. Отсутствие отступа в #defines затрудняет их чтение. А сочетание кода с отступом и кода с отступом #defines - это кошмар.

Распространенным решением является комментирование директив, чтобы вы могли легко понять, к чему они относятся:

#ifdef FOO
/* a lot of code */
#endif /* FOO */

#ifndef FOO
/* a lot of code */
#endif /* not FOO */
2
ответ дан 24 November 2019 в 05:51
поделиться

Почти во всех в настоящее время доступных компиляторах C/CPP это не ограничивается, это до пользователя, чтобы решить, как Вы хотите выровнять код. Так счастливое кодирование.

1
ответ дан 24 November 2019 в 05:51
поделиться

Как уже было сказано, некоторые компиляторы Pre-ANSI требовали, чтобы # был первым символом в строке, но они не требовали присоединения к нему директивы препроцессора, поэтому отступы были проделал этот путь.

#ifdef SDCC
#  if DEBUGGING == 1
#    if defined (pic18f2480)
#      define FLASH_MEMORY_END 0x3DC0
#    elif defined (pic18f2580)
#      define FLASH_MEMORY_END 0x7DC0
#    else
#      error "Can't set  up flash memory end!"
#    endif
#  else
#    if defined (pic18f2480)
#      define FLASH_MEMORY_END 0x4000
#    elif defined (pic18f2580)
#      define FLASH_MEMORY_END 0x8000
#    else
#      error "Can't set  up flash memory end!"
#    endif
#  endif
#else
#  if DEBUGGING == 1
#    define FLASH_MEMORY_END 0x7DC0
#  else
#    define FLASH_MEMORY_END 0x8000
#  endif
#endif

Я часто встречал этот стиль в старых заголовках Unix, но я ненавижу его, поскольку синтаксическая окраска часто не работает в таком коде. Я использую очень заметный цвет для директив препроцессора, чтобы они выделялись (они находятся на мета-уровне, поэтому не должны быть частью обычного потока кода). Вы даже можете видеть, что SO не окрашивает последовательность полезным способом.

24
ответ дан 24 November 2019 в 05:51
поделиться
Другие вопросы по тегам:

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