-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Корректность теста PopBadArgs #26
Comments
Не совсем. В строках const size_t size = 5;
const int data_in[size] = {1};
stack_push(stack, &data_in, sizeof(data_in)); В стеке в итоге оказывается не 5 элементов {1, 0, 0, 0, 0}, а один элемент размера |
И еще уточню на всякий случай: рассматриваемый нами тест написан для проверки ситуации, в которой пользователь передал неверные аргументы в функцию Поэтому в этой строке EXPECT_EQ(stack_pop(stack, data_out, sizeof(data_out)), 0u); ожидается, что EXPECT_THAT(data_out, ::testing::Each(0)); мы просто проверяем, что библиотека нас не обманула, и действительно ничего не записала в |
Ваш запрос обратил мое внимание на другую проблему в тестах. Я на самом деле хотел, чтобы весь массив |
Спасибо! const int data_in[size] = {1};
stack_push(stack, &data_in, sizeof(data_in)); в нем будет лежать не [1,0,0,0,0], а в [1,1,1,1,1], потому не совсем корректно понял сам тест. |
Тут вы как раз полностью правы были) |
Я вам инвайт коллаборатора направил, если хотите добавлю в ревьюверы пулл-реквеста с исправлением теста |
Ответственность за корректность "вытаскивания" элементов из стека лежит не на пользователе? |
Да, буду за |
На пользователе. Он должен представить буфер, с размером не меньшим, чем размер верхнего элемента в стеке. Это следствие того, что данные в буфере не типизированы. |
Разве это тогда не проблема пользователя, что он предоставил размер массива меньший (из 4 * size(int)), чем размер элемента стека (5 * size(int))? |
Ну да, это его проблема) Но это не значит, что надо намеренно выходить за границы массива или нарушать гранулярность данных , обрезав их до нужного размера. Библиотека спокойно сообщает о том, что пользователь передал указатель на участок памяти недостаточного размера. Это стандартная практика в С. С другой стороны, если пользователь создал буфер размера 4 байта, а сам передал в |
Может есть смысл в ТЗ отдельно добавить требование проверки совпадения размеров полей, которые подает пользователь с размером элемента в стеке? Что-то вроде "стек должен обеспечивать корректный вывод данных" или "библиотека должна гарантировать соответствие размера выводимых из стека данных и поля пользователя". То, что данные не типизированные ещё не означает, что библиотека должна заботиться о пользователе, ограничивая пользователя, если он хочет вытащить данные в поле некорректного размера. |
Требования совпадения размеров буферов нет, есть требование достаточности размера буфера, предоставляемого пользователем. Если пользователь захочет, может предоставить буфер большего размера, чем размер данных в верхушке стека. Перечитал ТЗ, возможно этот момент и стоит отдельно обозначить. Что то вроде
Считаю сохранение целостности данных в стеке приоритетным по отношению к возможному странному желанию пользователя получить первые несколько байт данных с утерей остальных. Что делать, если пользователь просто ошибся или не знал заранее, какой размер данных на вершине стека? К тому моменту, как он поймет ошибку, данные будут уже утеряны. Сравните два варианта: // push some text
const char* message = "This is important text, do not lose it!";
hstack_t handler = stack_new();
if (handler != -1) {
stack_push(handler, message, strlen(message));
}
// 1. stack_pop pops data to buffer of insufficient size and silently erases data
char buffer[20] = {0};
unsigned int out = stack_pop(handler, buffer, sizeof(buffer));
// out = 20, *buffer = "This is important te", "xt, do not lose it!" is lost forever
// or...
// 2. stack_pop refuses to pop data to buffer of insufficient size
char* buffer = (char*)calloc(20, 1);
unsigned int out = stack_pop(handler, buffer, 20);
if (out == 0u) {
buffer = (char*)realloc(buffer, 40);
out = stack_pop(handler, buffer, 40);
// out = 39, buffer = "This is important text, do not lose it!"
} |
Благодарю за уточнение. Подправлю этот момент в своём домашнем.
Выглядит здорово!
Согласен, но изначально по ТЗ не совсем понятно, должна ли библиотека отслеживать такое странное желание пользователя. Поскольку это требует отдельной проверки, а ТЗ не предъявляло такого требования, то могла случиться "оптимизация на проверку": зачем проверять то, что не требуют проверять. Приведенное уточнение ТЗ должно сделать картину яснее |
В данном тесте предлагается сделать вложение в стек массива из 5 элементов
После этого создаётся выходной массив, состоящий из 4-х элементов и идет обращение к стеку, чтобы получить данные
Тестирующая программа ожидает получить на выходе четыре 0,
Но это значит, что программа ожидает поэлементного добавления массива в стек, что-то вроде
В ТЗ особых требований по работе с массивом элементов не было, но есть указание, что данные не типизированы. Разумно расценивать массив, как один элемент, который загружается в стек. Поскольку индексирование массива идёт с первого элемента, то разумно ожидать на выходе из стека [1,0,0,0], а не [0,0,0,0]
The text was updated successfully, but these errors were encountered: