Соберите адреса всех статических строк C во время компиляции - PullRequest
0 голосов
/ 23 мая 2018

Допустим, у меня есть функция типа

void foo(const char* bar, ...)

И она была вызвана в нескольких местах.

Можно ли собрать адреса всех статических строк, которые известны во время компиляциив main()?

Например, foo("abc"), я хочу, чтобы в main() можно было получить адрес "abc".Если кто-то звонит foo(someVariable), адрес someVariable может быть неизвестен, и поэтому его можно игнорировать.

Возможно ли это?

Ответы [ 2 ]

0 голосов
/ 06 июня 2018

Если вы согласны использовать регистрацию, вы можете сделать что-то вроде

// Would contain each registered string.
std::vector<const char*>& registered_vector()
{
    static std::vector<const char*> v;
    return v;
}

bool Register(const char* s)
{
    registered_vector().push_back(s);
    return true;
}

// Class which holds the unique pointer as buffer.
template <typename Char, Char... Cs>
struct static_string
{
    static constexpr Char s[] = {Cs..., 0};
};

template <typename Char, Char... Cs>
constexpr Char static_string<Char, Cs...>::s[];

// string literal operator templates are a GNU extension
// MACRO can replace the operator to avoid that extension.
template <typename Char, Char... Cs>
static_string<Char, Cs...> operator ""_ss()
{
    static_string<Char, Cs...> res;
    static const bool dummy = Register(res.s); // Register only once :-)
    static_cast<void>(dummy); // Avoid warning for unused variable
    return res;
}

А теперь протестируйте его:

int main() {
    "Hello"_ss;
    "World"_ss;
    "Hello"_ss;
    "Hi"_ss;
    "42"_ss;

    for (const auto s : registered_vector()) {
        std::cout << s << std::endl;
    }
}

Демо

0 голосов
/ 23 мая 2018

Можно ли собрать адреса всех статических строк, которые известны во время компиляции в main()?

Во время компиляции строки из других модулей перевода недоступны.

Вы можете записать строковые литералы из исполняемой или общей библиотеки с помощью команды readelf -W -p .rodata <executable>.

...