Является ли это использование макросов в C переносимым?

#c #macros #c-preprocessor

#c #макросы #c-препроцессор

Вопрос:

Эта программа на языке Си определяет НАЧАЛО и КОНЕЦ макросов, которые генерируют информацию о выполнении функции времени выполнения. Действия TRACE_START и TRACE_END могут быть любыми, конечно, например, выталкивание и выталкивание стеков, динамическое профилирование и т.д. Кроме того, нет причин, по которым поведение действия не может быть настроено во время выполнения. Это предлагает много привлекательных возможностей для определенных типов программных продуктов.

С другой стороны, начинается переопределение открывающих и закрывающих фигурных скобок функций с f(){} на f() …END, вероятно, сломает многие автоматические инструменты. Принимая во внимание, что это так, каковы последствия этого? Является ли это использование макропроцессора переносимым?

Приведенный ниже код корректно компилируется с помощью gcc -pedantic .

 #include <stdio.h>

#define START           {TRACE_START
#define END             TRACE_END}
#define TRACE_START     printf("ENTERING %sn", __func__);
#define TRACE_END       printf("LEAVING %sn", __func__);

int func()
START
    printf ("Hello World %sn");
END

int main()
START
    func();
END
  

и выдает вывод

 ENTERING main
ENTERING func
Hello World
LEAVING func
LEAVING main
  

Заранее благодарю вас за ваши проницательные комментарии.

Комментарии:

1. Предполагается, что препроцессор не должен заботиться о синтаксисе результатов своих расширений, а компилятор не должен заботиться о том, какая магия препроцессора произвела его ввод. AFAIK это совершенно законно, хотя и ужасно.

2. Код как есть строго соответствует тому, что определяет стандарт C, поэтому он переносим в этом смысле. Как вы заметили, это может не работать с автоматическими инструментами. Также нельзя полагаться на работу с другим исходным кодом в целом, поскольку другой исходный код может иметь свое собственное применение для START , END , и так далее. По мере того, как вы прогрессируете как программист, вы, как правило, научитесь избегать подобных ошибок. Нет особых причин удалять { и } . Процедуры могут быть инструментированы просто путем размещения START END макросов and с { помощью and } вместо них.

3. Обратите внимание, что нет никаких оснований ожидать, что произвольная функция когда-либо достигнет END , поскольку функции могут возвращаться с return операторами (или с longjmp или exit или abort и другими).

4. Функции, не являющиеся пустыми, даже необходимы, чтобы не достигать END .

5. Это «переносимо» в том смысле, что каждый компилятор, соответствующий стандарту, должен его принимать. Однако это крайне нетрадиционно и, как вы заметили, скорее всего, плохо взаимодействует с IDE, инструментами анализа кода, программистами форматирования кода и другими людьми, которые пытаются прочитать код.

Ответ №1:

Является ли это использование макросов в C переносимым?

ДА.

каковы последствия этого?

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

Является ли это использование макропроцессора переносимым?

ДА.