"#define BUF 8" против "#define BUF (8) - PullRequest
2 голосов
/ 16 апреля 2019

Какая разница (если есть) между:

#define BUF (8)

и

#define BUF 8

Я не очень опытен в программировании на c и никогда не видел #define только с одним числом и, кроме того, заключил его в скобки.

PS: код скомпилирован в 64-битной системе Linux с использованием gcc с флагом -m32. Таким образом, последний двоичный файл - 32-битный исполняемый файл ELF.

Ответы [ 3 ]

7 голосов
/ 16 апреля 2019

Внешний вид макро-идентификатора в области просто заменяется текстом замены. Таким образом, этот код ...

#define BUF 8
#define BUF2 (8)

x =  BUF * BUF2;

... расширяется до

x = 8 * (8);

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

В этом случае два макроопределения могут использоваться почти , но не полностью взаимозаменяемо. Однако в других контекстах скобки имеют большее значение. Учтите это:

#define MY_SIZE 16 + 7
#define MY_SIZE2 (16 + 7)

void *x = malloc(8 * MYSIZE);
void *y = malloc(8 * MYSIZE2);

Расширяется до

void *x = malloc(8 * 16 + 7);
void *y = malloc(8 * (16 + 7));

, который резервирует различные объемы памяти для x и y.

6 голосов
/ 16 апреля 2019

Я не могу себе представить, что это имеет какое-то значение при разумном использовании в данном конкретном случае, но учтите это:

#define add(x,y) x+y

int i=add(3,5)*2

Теперь вы ожидаете, что у меня будет значение 16, верно ?, но оно расширится до i = 3 + 5 * 2, что даст мне значение 13.

HolyBlackCat написал в комментарии, что float x = sin BUF; не будет компилироваться в последнем случае, и это полностью верно. Однако использование таких макросов - ОЧЕНЬ плохая идея.

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

По аналогичным причинам, если макрос содержит несколько операторов, рекомендуется заключить их в цикл do-while. Учтите это:

#define callMy2Funcs(x,y) \
    myFunc1(x); \
    myFunc2(y);

Теперь вот это:

if(x>5) 
    callMy2Funcs(x,x);

расширится до

if(x<5)
    myFunc1(x);
myFunc2(x);

вместо

if(x<5) {
    myFunc1(x);
    myFunc2(x);
}

Решение таково:

#define callMy2Funcs(x,y) \
    do {\
        myFunc1(x); \
        myFunc2(y); \
    } while(0)
2 голосов
/ 16 апреля 2019

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

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

#define CONSTANT_A 2
#define CONSTANT_B 1
#define CONSTANT_C 0
#define CONSTANT_D (-1)

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

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