C++, препроцессор, условная компиляция и ODR

158
17 ноября 2021, 13:20

Я провожу небольшое исследование существующих способов нарушить ODR (Правило Единого Определения) при использовании inline, и меня интересует следующее.

  1. У меня есть некоторые сомнения в том, в какой последовательности происходит препроцессинг и условная компиляция. Например, include и ifdef. Буду благодарен, если кто-нибудь сможет уточнить этот момент.

  2. Можно ли нарушить ODR при использовании условной компиляции в inline функциях/методах?

    Например:

    func.hpp:

    inline void func()
    {
        // ...
    #ifdef X
        // ...
    #endif
        // ...
    }
    

    a.cpp:

    #define X
    #include "func.hpp"
    void a_func()
    {
        func();
    }
    

    b.cpp:

    #undef X
    #include "func.hpp"
    void b_func()
    {
        func();
    }
    

    Я полагаю, что сначала происходит подстановка содержимого файла (в местеinclude), а уже потом - условная компиляция. Следовательно, данный код нарушает ODR и приводит к неопределенному поведению. Все происходит именно так?

  3. Можно ли избавиться от нарушения ODR, если define и include поменять местами?

Answer 1

1. Я так понимаю, вопрос в том, видно ли в заголовочных файлах макросы, определенные в тех файлах, которые эти заголовки включают? Да, конечно видно. Иначе, например, include guard'ы бы не работали.

В вашем примере, #define X в a.cpp влияет на #ifdef X в func.hpp. (Конечно, если #define X находится выше #include "func.hpp")

2. Да, тут ODR нарушен.

3. Да, это уберет нарушение ODR, потому что функции станут одинаковыми. #ifdef X будет обработан раньше, чем #define X.

READ ALSO
Решить задачу с помощью рекуррентного соотношения, алгоритмы (С++)

Решить задачу с помощью рекуррентного соотношения, алгоритмы (С++)

Назовём число счастливым, если оно делится на k и сумма его цифр лежит в интервале [p, q]Нужно подсчитать, сколько счастливых чисел лежат в интервале...

130
Как быстро проверить делимость числа?

Как быстро проверить делимость числа?

Есть 2 числа, нужно найти за короткое время на КАКИЕ числа они оба делятся без остатка? Как это можно сделать? Если пытаться обычным циклом,...

161
Проблема с таймингом

Проблема с таймингом

Вечер добрыйЕсть программа для эмуляции

99
скрыть часть option на bootstrap

скрыть часть option на bootstrap

как в bootstrap в выподающем списке скрыть часть option ? есть список

163