Pull to refresh

Comments 9

Интересно а на манер rust не получится пометить функции тесты каким нибудь атрибутом из тех что в стандарте имеются?

В стандарте — не уверен. В перечне стандартных ничего подходящего нет, вроде бы.


С помощью макросов по идее можно облагородить [[gnu::section("test")]] или __attribute__((section("tests"))). Тогда все тестовые функции и данные можно разместить в отдельной секции, что даёт ряд плюшек:


  • нет путаницы с тестовыми функциями и остальными
  • линкер может выкинуть всё тестовое добро при сборке
В плюсах нет возможности в рантайме посмотреть все ф-и с таким-то атрибутом. Даже предлагаемые пропозалы, по-моему, по статической рефлексии не включают в себя возможность в компайл тайме узнать атрибуты ф-и. Мне кажется, атрибуты также не влияют на name mangling, то есть по символам ф-й также не получится что-либо узнать.
Без сторонней тулзы, которая парсит код, не получится. Или я что-то упустил?

Не получится, да. В статье как раз и используются «внешние» средства для интроспекции. В том смысле, что приходится прибегать к парсерам, которые разбирают бинарный файл или образ библиотеки и достают информацию оттуда. В противоположность, когда эта информация изначально программным образом доступна самой программе. В принципе, ничто также не мешает программе распарсить свой собственный образ в памяти и найти там информацию, которую возможно сохранил динамический загрузчик.


Я про атрибуты имел в виду то, что можно, скажем, написать


#include <iostream>

[[gnu::section("__TEXT,__tests")]]
void run_test()
{
    std::cout << "run_test()\n";
}

void test_function()
{ 
    std::cout << "test_function()\n";
}

тогда функции run_test и test_function попадут в разные секции:


$ nm -gU libtest.dylib -s __TEXT __text | grep test
0000000000001380 T __Z13test_functionv
$ nm -gU libtest.dylib -s __TEXT __tests | grep test
0000000000001e80 S __Z8run_testv

Таким образом удобнее фильтровать именно функции-тесты, рассматривая только секцию __tests.


По идее, можно даже вырезать секцию с тестами из файла при сборке, но я не очень силён в скриптах для компоновщика.

Для вырезки секций есть что-то вродe objcopy -j.

Linux, старая оболочка GNOME 2.
Интересно, я смотрел различные библиотеки тестирования на С++, но не смотрел библиотеки для С, а тут такая оказывается бывает такая годнота.

extern "C" и не будет никакого mangling функций на верхнем уровне. Так что посыл "живите с этим" в корне неверен.

Sign up to leave a comment.

Articles