Может ли компилятор исключить тела функций, которые принимаются по адресу, но никогда не вызываются?
Рассмотрим эту упрощенную реализацию std::any
(нерелевантные части опущены) и некоторый код, который его использует:
namespace std {
namespace details {
// Each instance of this function template has a different address
template <typename T>
const char *dummy_function() { return __PRETTY_FUNCTION__; }
template <typename T> void *construct(T &&);
void destroy(void *storage, const char *(*type_identifier)());
}
class any {
const char *(*type_identifier)();
void *storage;
public:
template <typename Arg>
any(Arg &&arg)
: type_identifier(&details::dummy_function<decay_t<Arg>>)
, storage(details::construct(forward<Arg>(arg))) {}
template <typename Arg>
any &operator=(Arg &&arg) {
details::destroy(storage, type_identifier);
type_identifier = &details::dummy_function<decay_t<Arg>>;
storage = details::construct(forward<Arg>(arg));
}
template <typename T>
friend T *any_cast(any *source) {
if (source && source->type_identifier == &dummy_function<T>)
return static_cast<T *>(source->storage);
return nullptr;
}
};
}
#include <any>
// Code that compares any::type_identifier a lot but never calls through it
std::any any = 42;
assert(std::any_cast<int>(&any) != nullptr);
assert(std::any_cast<double>(&any) == nullptr);
any = std::string("Hello");
assert(std::any_cast<std::string>(&any) != nullptr);
assert(std::any_cast<std::vector<char>>(&any) == nullptr);
Если оптимизирующий компилятор может доказать, что std::details::dummy_function<T>
никогда не вызывается каким-либо образом на протяжении всей программы, разрешено ли компилятору не включать тело функции std::details::dummy_function<T>
(вместе с тем самым не упоминаемым __PRETTY_FUNCTION__
s) для любых T
в результате компиляции (и даже, возможно, сделать свои адреса произвольными целыми числами размером с указатель, которые гарантированно будут отличаться друг от друга, но в противном случае могут даже не быть действительными адресами памяти)?
(Или даже адреса, не гарантированно отличимые для разных T
s, что, к сожалению, означает, что моя реализация изначально неверна?)