Комментарии 11
Я провел следующий эксперимент:
В программе, скомпилированной clang просто произошел вызов функции, а вот с gcc интереснее: генерируется вообще некорректный код.
Если вызов был произведен через указатель на "void()const", то код вызова отсутствует совсем, если же const заменить на volatile или const volatile, то функция вызывается, но после программа падает (код вызывающей функции обрывается после вызова).
Кстати, в VC++ проверка, видимо, есть, но она не работает из-за другого бага: код автора компилируется только когда параметр функции, который должен стать указателем, является безымянным. Если же имя у парамтра есть, то мы всё же получаем желаемую ошибку:
При этом, если проверку всё же обойти, то std::is_same для типов указателей на "void()const" и "void()volatile" возвращает false, но любое другое использование данных типов указывает на то, что компилятор их не различает.
В целом, действительно интересная статья, автору спасибо. Мне понравился итоговый способ, хотя, конечно, всем уже давно пора перейти на новый стандарт языка.
- Получаем обманным путем (с помощью примера с Extract из баг-репорта автора к gcc) указатель на "void()const".
- Присваиваем данному указателю адрес non-member функции. (Причем, в clang нужен cast, в gcc — не нужен).
- Вызываем функцию с помощью этого указателя.
В программе, скомпилированной clang просто произошел вызов функции, а вот с gcc интереснее: генерируется вообще некорректный код.
Если вызов был произведен через указатель на "void()const", то код вызова отсутствует совсем, если же const заменить на volatile или const volatile, то функция вызывается, но после программа падает (код вызывающей функции обрывается после вызова).
Кстати, в VC++ проверка, видимо, есть, но она не работает из-за другого бага: код автора компилируется только когда параметр функции, который должен стать указателем, является безымянным. Если же имя у парамтра есть, то мы всё же получаем желаемую ошибку:
error C2270: 'value': modifiers not allowed on nonmember functions
note: see reference to class template instantiation 'S<void (void) volatile>' being compiled
При этом, если проверку всё же обойти, то std::is_same для типов указателей на "void()const" и "void()volatile" возвращает false, но любое другое использование данных типов указывает на то, что компилятор их не различает.
В целом, действительно интересная статья, автору спасибо. Мне понравился итоговый способ, хотя, конечно, всем уже давно пора перейти на новый стандарт языка.
+1
Просто шикарный разбор, спасибо.
Независимо от практического применения может быть использован и как тьюториал и как база для др. конструкций.
Независимо от практического применения может быть использован и как тьюториал и как база для др. конструкций.
+2
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Другая реализация метафункции is_function<T> для C++98/03