Концептуальный wish-you-happy-debug

Nov 07, 2024 14:11


Ужасы программизма, запостил на RSDN (а потом подшлифовал и запостил на Хабр)

Маленькая глупенькая загадка-вотзефак. Не из рабочего кода, к счастью, но, как говорится, был близок к тому :)))

Представьте себе, что у вас в коде есть функция f(x) и концепт fable, отвечающий на вопрос - можно ли подставить этот тип в f.

Но этот концепт работает... как-то странно!
Поэтому сделаем два одинаковых концепта - просто скопипастим их.
И даже напишем функцию, которая проверяет их оба.

До того, как всё сломалось, - всё работало: https://gcc.godbolt.org/z/dPPE6KrYe



А потом что-то сломалось. https://gcc.godbolt.org/z/T5G7rox33 (я удалил ключевой код, естественно).

#include

template concept fable1 = requires(const T& t) { f(t); };
template concept fable2 = requires(const T& t) { f(t); };

template void g() {
if constexpr (fable1) {
std::cout << "fable" << std::endl;
} else if constexpr (fable2) {
std::cout << "wtf" << std::endl;
} else {
std::cout << "non-fable" << std::endl;
}
}

struct A{}; // fable
struct B{}; // non-fable
struct C{}; // wtf

/*
something wrong happens
*/

void f(A) {} // fable
void f(C) {} // fable ???

static_assert( fable1 && fable2);
static_assert(!fable1 && !fable2);
static_assert( fable1 != fable2); // wtf

int main() {
g(); // fable
g(); // non-fable
g(); // wtf
}

Два одинаковых концепта. Один true, другой false, два весёлых концепта!

Попробуйте догадаться, в чём дело.

А если догадаетесь, то попробуйте написать минималистичный wish-you-happy-debug

Отгадка: https://gcc.godbolt.org/z/jorvdj7MY

Причина очень проста: [подождите открывать, подумайте.]где шаблон (а концепт - это шаблон булевой константы) инстанцирован, там он и получил значение. А в этой точке функция f(C) ещё не видна.

UPD. Днище ада оказалось двойным и чуть более глубоким:

Св.Писание, 13.5.2.3 (параграф 3, предложение 5)  [в тексте есть спойлер, поэтому прячу с глаз]If, at different points in the program, the satisfaction result is different for identical atomic constraints and template arguments, the program is ill-formed, no diagnostic required.

Давным-давно АлёнаС++ нарисовала шикарную карту языка в духе великих географических открытий, со львами-драконами-псьеглавцами. Надо бы обновить! alenacpp, ау.

ужасы, внезапно, программирование, c++, дурево

Previous post Next post
Up