При компиляции этого фрагмента кода (пример кода)
#include <iostream>
#include <cstdlib>
#include <chrono>
#ifndef USE_DEFINE
class ClassA
{
public:
inline static constexpr uint8_t A = 0;
};
#else
#define A 0
#endif
int main()
{
srand(std::chrono::system_clock::now().time_since_epoch().count());
uint8_t a = rand() % 255;
#ifndef USE_DEFINE
if(a < ClassA::A)
#else
if(a < A)
#endif
{
std::cout << "Shouldn't even compile using `-Wall -Wextra -Werror -Wfatal-errors -Wpedantic` flags." << std::endl;
return -1;
}
return 0;
}
с G CC 7.5 и следующими флагами
g++ -std=gnu++17 -Wall -Wextra -Wpedantic -Wfatal-errors -Werror -o test main.cc
я получаю следующее предупреждение / ошибка (из-за -Werror
):
main.cc: In function ‘int main()’:
main.cc:40:7: error: comparison is always false due to limited range of data type [-Werror=type-limits]
40 | if(a < ClassA::A)
Что мне кажется нормальным из-за того, что я пытаюсь проверить, меньше ли uint8_t
, чем 0
. То же самое происходит при определении USE_DEFINE
. Оба выражения не являются константами из-за изменяющегося значения a
, поэтому можно проверить, позволяют ли ограничения типа этот вид сравнения оценивать как true
AND false
.
То же самое с более новый компилятор (G CC 10.1.0 / CLang 10.0.1) я больше не получаю это предупреждение при использовании inline static constexpr uint8_t A = 0
из ClassA
. Когда я использую USE_DEFINE
, происходит то же самое.
Это поведение GCC / Clang ошибочно или это побочный эффект, вызванный атрибутами const/constexpr
?
G CC -Manual говорит (для G CC 6.4 / 7.5, а также 10):
-Wtype-limits
Предупреждать, если сравнение всегда верно или всегда ложно из-за ограниченного диапазона тип данных, но не предупреждать о постоянных выражениях. Например, предупредить, если беззнаковая переменная сравнивается с нулем с помощью <или> =. Это предупреждение также активируется -Wextra.
Насколько я понимаю, if(a < ClassA::A)
не является постоянным выражением, хотя я использую ключевое слово constexpr
. То же самое происходит при использовании const
вместо constexpr
. Что приводит к такому поведению?