Я провожу небольшое исследование существующих способов нарушить ODR
(Правило Единого Определения
) при использовании inline
, и меня интересует следующее.
У меня есть некоторые сомнения в том, в какой последовательности происходит препроцессинг и условная компиляция. Например, include
и ifdef
. Буду благодарен, если кто-нибудь сможет уточнить этот момент.
Можно ли нарушить 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
и приводит к неопределенному поведению. Все происходит именно так?
Можно ли избавиться от нарушения ODR
, если define
и include
поменять местами?
1. Я так понимаю, вопрос в том, видно ли в заголовочных файлах макросы, определенные в тех файлах, которые эти заголовки включают? Да, конечно видно. Иначе, например, include guard'ы бы не работали.
В вашем примере, #define X
в a.cpp
влияет на #ifdef X
в func.hpp
. (Конечно, если #define X
находится выше #include "func.hpp"
)
2. Да, тут ODR нарушен.
3. Да, это уберет нарушение ODR, потому что функции станут одинаковыми. #ifdef X
будет обработан раньше, чем #define X
.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Назовём число счастливым, если оно делится на k и сумма его цифр лежит в интервале [p, q]Нужно подсчитать, сколько счастливых чисел лежат в интервале...
Есть 2 числа, нужно найти за короткое время на КАКИЕ числа они оба делятся без остатка? Как это можно сделать? Если пытаться обычным циклом,...
как в bootstrap в выподающем списке скрыть часть option ? есть список