WedX - журнал о программировании и компьютерных науках

Пример часто задаваемых вопросов C++ по встроенному и #define

В FAQ есть пример, объясняющий разницу между inline и #define. Код находится здесь, а ссылка: https://www.parashift.com/c++-faq/inline-vs-macros.html

Пробовал с Visual C++, и unsafe(), и unsafe(f()) не увеличивали i дважды. В примере нет ошибки?

c++
07.12.2013

  • Почтовый код, а не ссылки на код. 07.12.2013
  • В примере нет никаких выходных данных — вам нужно показать, что вы сделали, чтобы показать значения. И на первый взгляд в этом примере нет никаких проблем. 07.12.2013
  • есть сравнение в макросе. Это сравнение вызывает функцию. Таким образом, он оценивается дважды. Кстати, этот сайт известен как довольно хороший, так что вы можете ему доверять. И проверьте все свои сомнения отладчиком 07.12.2013
  • Ссылка, о которой идет речь, в настоящее время не работает.... И именно вам следовало обратить внимание на комментарий nhgrif. 04.12.2017

Ответы:


1

Основная идея #define заключается в том, что это просто директива препроцессора, а это означает, что это:

#define unsafe(i) ( (i) >= 0 ? (i) : -(i) )

предварительно обработает ваш код перед его компиляцией и заменит оператор

unsafe(x++);

со следующим

((x++) >= 0 ? (x++) : -(x++));

Каждый раз, когда вычисляется x++, x увеличивается.

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

Если вы нигде не используете свой x, то он считается неиспользуемым и, следовательно, не включается в скомпилированный код.

07.12.2013
  • Я считаю, что это -O или -O2. Однако, если вы только учитесь, то я бы посоветовал не заморачиваться с этими флагами. Вместо этого обратите внимание, что для вашего решения (проекта) VC++ существует две конфигурации по умолчанию, а именно Debug и Release. Первый не использует оптимизацию, поэтому я предлагаю запустить пример кода в Debug, а второй оптимизирует с использованием некоторых методов оптимизации по умолчанию, включая тот, который я описал выше. 08.12.2013

  • 2

    Только что проверил пример, проверьте ответ Эрика Гопака для объяснения:

    // A macro that returns the absolute value of i
    #define unsafe(i)  \
        ((i) >= 0 ? (i) : -(i))
    
    // An inline function that returns the absolute value of i
    inline
    int safe(int i)
    {
        return i >= 0 ? i : -i;
    }
    
    int countCalls = 0;
    
    int f()
    {
        return countCalls++;
    };
    
    int main()
    {
        int x = 0;
        int ans = 0;
    
        ans = unsafe(x++);   // Error! x is incremented twice
        ans = unsafe(f());   // Danger! f() is called twice
    
        // x = 2
        // countCalls = 2
    
        ans = safe(x++);     // Correct! x is incremented once
        ans = safe(f());     // Correct! f() is called once
    
        // x = 3
        // countCalls = 3
    
        return 0;
    }
    
    07.12.2013
  • странно, я использовал ваш код (на самом деле мой такой же), но получил x = 1 от обоих вызовов unsafe(). какой компилятор вы используете? Я использую Visual C++ Express 2010. Какие параметры компилятора вы используете? Все, что я использовал, было по умолчанию. 07.12.2013
  • @user3078106 user3078106 вы должны получить ответ = 0, потому что это приращение сообщения, но ответ = 1. 07.12.2013
  • @user3078106 user3078106 Я использую Visual Studio 2013, теперь я также проверил это в 2010 году, что дает тот же результат (как я и ожидал). Возможно ли, что вы запускаете свою программу в режиме Release? Значениям, предоставленным в режиме выпуска, не всегда можно доверять. См. этот ответ 07.12.2013
  • Нет, я всегда тестирую в режиме отладки. 07.12.2013
  • Я понял. Но почему uk4321 сказал, что должен получить ответ = 0, потому что это приращение поста, но ответ = 1? Откуда инкремент поста? 08.12.2013
  • @user3078106 user3078106 Он, вероятно, хочет сказать, что когда вы отлаживаете и находитесь в точке ans = unsafe(x++);, ans будет иметь значение 0. В точке ans = unsafe(f()); ans будет иметь значение 1. Короче говоря, второе приращение ans первого Функция unsafe() "зафиксирована" во второй функции unsafe() 08.12.2013
  • Новые материалы

    Как создать диаграмму градиентной кисти с помощью D3.js
    Резюме: Из этого туториала Вы узнаете, как добавить градиентную кисть к диаграмме с областями в D3.js. Мы добавим градиент к значениям SVG и применим градиент в качестве заливки к диаграмме с..

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..


    Для любых предложений по сайту: [email protected]