Если имя функции отсутствует, как в вашем первом примере, тогда это не «оператор скобок». Это просто синтаксический элемент выражения, который изменяет связь между операторами и операндами. В этом случае он просто ничего не делает. То, что у вас есть, это просто выражение
"Hello world";
, которое оценивается как значение типа char *
, и это значение игнорируется. Вы можете заключить это выражение в избыточную пару ()
("Hello world");
, который ничего не изменит.
Точно так же, как вы можете написать
(5 + 3);
в середине вашего кода и получите выражение, которое оценивается в значение 8
, которое немедленно отбрасывается.
Обычно компиляторы не генерируют код для выражений, которые не имеют побочных эффектов. Фактически, в языке C результат каждого оператора выражения отбрасывается, поэтому единственные операторы выражения, которые «имеют смысл», являются операторами выражения с побочными эффектами. Компиляторы, как правило, довольно хороши в обнаружении бесполезных операторов и их отбрасывании (иногда с предупреждением).
Предупреждение может быть раздражающим, поэтому написание выражений без эффекта, таких как
"Hello world";
не может быть хорошей идеей. Обычно компиляторы распознают приведение к void
как запрос не генерировать это предупреждение
(void) "Hello world";
Так что вы можете рассмотреть возможность переопределения вашего макроса соответственно.
Конечно, используя вышеописанную технику trace
, вы должны помнить, что если вы добавите что-то, что имеет побочный эффект в качестве аргумента для вашего макроса
trace("%d\n", i++);
тогда в «отключенном» виде это будет выглядеть следующим образом
("%d\n", i++);
(два подвыражения, объединенные оператором запятой в одно выражение). Побочный эффект увеличения i
сохраняется в этом случае, он не отключается. Все это эквивалентно простой
i++;
Также, если вы используете вызов функции в качестве аргумента
trace(get_trace_name());
«отключенная» форма будет выглядеть как
(get_trace_name());
и компилятор может быть недостаточно умен, чтобы понять, что вызов get_trace_name()
следует отбросить. Так что будьте осторожны при использовании вашего макроса. Избегайте аргументов с побочными эффектами, избегайте аргументов с вызовами функций, если, конечно, вы не намерены сохранять побочные эффекты при отключении фактической трассировки.