Препроцессор C разделяет комментарии или разворачивает макросы сначала? [дубликат]

Нет к моему знанию никакого стандарта. За время я нашел, что эти инструкции полезны:

  • краткие названия Использования, потому что они не делают строки в файле журнала слишком долго.

  • Создают имена, где важная часть вначале. Средства просмотра журнала в графическом интерфейсе пользователя имеют тенденцию иметь таблицы со столбцами, и столбец потока является обычно маленьким или будет сделан маленьким Вами для чтения всего остального.

  • не используют слово "поток" на имя потока, потому что это очевидно.

  • делают имена потока легко grep-способными. Избегайте подобных звучащих имен потока

  • , если Вы имеете несколько потоков аналогичного характера, перечисляете их с идентификаторами, которые уникальны для одного выполнения приложения или одного файла журнала, какой бы ни соответствует Вашим привычкам входа.

  • избегают обобщений как "WorkerThread" (как Вы называете следующие 5 рабочих потоков?), "GUIThread" (который GUI? это для одного окна? для всего?) или "Вычисление" (что это вычисляет?).

  • , если у Вас есть тестовая группа, которая использует имена потока к grep файлы журнала Вашего приложения, не переименовывайте свои потоки через какое-то время. Ваши тестеры будут ненавидеть Вас за то, что Вы сделали так. Имена потока в хорошо протестированных приложениях должны установиться.

  • , когда у Вас есть потоки, которые обслуживают сетевое соединение, попытайтесь включать адрес сети назначения в имя потока (например, channel_123.212.123.3). Не забывайте о перечислении хотя, если существуют многочисленные связи к тому же хосту.

, Если Вы имеете много потоков и забыли называть один, Ваш механизм журнала должен произвести уникальный идентификатор потока вместо этого (определенный для API, например, путем вызова pthread_self ())

54
задан Deduplicator 30 June 2016 в 09:24
поделиться

5 ответов

Unfortunately, the original ANSI C Specification specifically excludes any Preprocessor features in section 4 ("This specification describes only the C language. It makes no provision for either the library or the preprocessor.").

The C99 specification handles this explicity, though. The comments are replaced with a single space in the "translation phase", which happens prior to the Preprocessing directive parsing. (Section 6.10 for details).

VC++ and the GNU C Compiler both follow this paradigm - other compilers may not be compliant if they're older, but if it's C99 compliant, you should be safe.

32
ответ дан 7 November 2019 в 08:10
поделиться

Согласно MSDN , на этапе токенизации комментарии заменяются одним пробелом, что происходит перед этапом предварительной обработки, на котором раскрываются макросы.

5
ответ дан 7 November 2019 в 08:10
поделиться

Никогда не помещайте // комментарии в свои макросы. Если вы должны добавить комментарии, используйте / * * /. Кроме того, в вашем макросе есть ошибка:

#define foo(x) do { } while(0) /* junk */

Таким образом, foo всегда безопасно использовать. Например:

if (some condition)
    foo(x);

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

4
ответ дан 7 November 2019 в 08:10
поделиться

Как описано в , это дешифрование с копированием и вставкой фаз перевода в стандарте C99, удаление комментариев (они заменяются одним пробелом) происходит на этапе перевода 3, в то время как директивы предварительной обработки обрабатываются, а макросы расширяются на этапе 4.

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

Опять же, стандарт C ++ имеет эти 2 фазы происходят в одном порядке.

Что касается того, как следует обрабатывать комментарии ' // ',в стандарте C99 сказано следующее (6.4.9 / 2):

За исключением символьной константы, строкового литерала или комментария, символы // ввести комментарий, который включает все многобайтовые символы до, но не включая, следующий символ новой строки.

И стандарт C ++ говорит (2.7):

Символы // начинают комментарий, который заканчивается следующей новой строкой

Итак, ваш первый пример явно является ошибкой со стороны этого переводчика - символ '; ' после foo (a) должен быть сохранен, когда ] foo () макрос расширен - символы комментария не должны быть частью «содержимого» макроса foo () .

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

#define foo(x) /* junk */

, чтобы обойти ошибку.

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

#define evil( x) printf( "hello "); // hi there, \
                 printf( "%s\n", x); // you!



int main( int argc, char** argv)
{
    evil( "bastard");

    return 0;
}

Что может удивить того, кто его написал.

Или, что еще лучше, попробуйте следующее, написанное кем-то (конечно, не мной!), кому нравится box- комментарии к стилю:

int main( int argc, char** argv)
{
                            //----------------/
    printf( "hello ");      // Hey, what the??/
    printf( "%s\n", "you"); // heck??         /
                            //----------------/
    return 0;
}

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

10
ответ дан 7 November 2019 в 08:10
поделиться

I seem to recall that compliance requires three steps:

  1. strip
  2. expand macros
  3. strip again

The reason for this has to do with the compiler being able to accept .i files directly.

1
ответ дан 7 November 2019 в 08:10
поделиться
Другие вопросы по тегам:

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