GCC typeof расширение и математика на typeof результате - PullRequest
3 голосов
/ 04 июня 2019

Сегодня я наткнулся на этот макрос в ядре Linux (include/linux/kernel.h)

#define DIV_ROUND_CLOSEST(x, divisor)(          \
{                           \
    typeof(x) __x = x;              \
    typeof(divisor) __d = divisor;          \
    (((typeof(x))-1) > 0 ||  /* <-- why does this work */   \
     ((typeof(divisor))-1) > 0 || (__x) > 0) ?  \
        (((__x) + ((__d) / 2)) / (__d)) :   \
        (((__x) - ((__d) / 2)) / (__d));    \
}                           \
)

Теперь я понимаю назначение макроса и то, что он каким-то образом использует «выражения выражений» (ссылка ниже упоминает об этом). Что я не понимаю, так это то, как ((typeof(x))-1) > 0 означает что-то полезное. Из этой ссылки в gcc docs, я думаю, я понимаю, как предполагается использовать расширение typeof. Но зная, что это не похоже на то, как это используется в этом макросе. Судя по моим собственным экспериментам, (typeof(x)-1) не похоже ни на что, кроме -1, поэтому разве это всегда не будет меньше 0 (т. Е. Ложно для первые две части троичной)?


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

1 Ответ

6 голосов
/ 04 июня 2019

Он не использует (typeof(x)-1) - он использует ((typeof(x))-1), который имеет форму (type)value - т.е. это выражение приведения.

Он приводит значение -1 к тому же типу, что и выражение x, и затем проверяет, является ли результат больше нуля. Если x имеет целочисленный тип со знаком или тип с плавающей точкой, результат будет ложным, если x имеет целочисленный тип без знака, то результат будет истинным, а для большинства других типов поведение будет неопределенным.

...