C ++ макро побочный эффект - PullRequest
0 голосов
/ 25 марта 2012

Я не понимаю, почему результат будет 36. Может кто-нибудь объяснить мне, что здесь происходит и что делает препроцессор?

#include <iostream>
#define QUADRAT(x) ((x) * (x))

using namespace std;

int main()
{
    double no = 4.0;
    double result = QUADRAT(++no);

    cout << result;
    return 0;
}

Большое спасибо:>

Ответы [ 4 ]

4 голосов
/ 25 марта 2012

Препроцессор заменит QUADRAT(++no) на ((++no) * (++no)) в этом примере.

Это увеличило бы no в два раза, если бы не тот факт, что между двумя приращениями нет точек последовательностиТаким образом, вы на самом деле вызывает неопределенное поведение.Любой вывод, который вы видите, действителен, потому что никто не может сказать, что произойдет.

2 голосов
/ 25 марта 2012

Препроцессор - это, по сути, механизм копирования и вставки.Обратите внимание, что макрос не функция;вместо этого он расширяется встроенным.Подумайте, что происходит с вашим кодом при раскрытии макроса.

1 голос
/ 25 марта 2012

Эта строка:

double result = QUADRAT(++no);

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

double result = ((++no) * (++no));

Способ, которым это заканчивается, эквивалентен:

no = no + 1;
no = no + 1;
result = no * no;

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

inline double QUADRAT(double x) { return x * x; }

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

0 голосов
/ 25 марта 2012

То, что происходит, является своего рода буквальной заменой ++ вместо x, это как вы написали:

double result = ((++no) * (++no));

Каков результат ... это должно быть неопределенное поведение (выполучи 36 случайно), а g ++ с -Wall согласен со мной.

...