Есть ли способ ограничить размер данных во время компиляции C ++ и вызвать ошибку компиляции? - PullRequest
2 голосов
/ 30 марта 2019

У меня есть инструмент, позволяющий учащимся компилировать и тестировать собственный код C ++ в режиме онлайн (в защищенной среде).

Я хотел бы проверить, во время компиляции, что общий объем данных в программе не превышает определенный размер, и вызвать ошибку компиляции, если это так.

(непосредственная цель: ограничение c ++ std :: size array)

Я не нашел информации в Интернете.

Моя цепочка компиляции:

g++ -Wall -Wextra -Waddress -std=c++11 -lm -fstack-protector -lm -o exename srcname

Спасибо за помощь.

РЕДАКТИРОВАТЬ 1

Я даю им скелет, и они должны завершить, где (здесь) указано:

«Завершите программу (здесь) определением« produitTableau », которое получает двумерный массив целых чисел и целое число, применяет функцию« calcul »к каждому из своих значений и возвращает измененный массив». (по-французски ...)

#include <iostream>
#include <array>
using namespace std;

const int NB = 3;

int calcul (int a, int b);
array<array<int, NB>,NB> produitTableau(array<array<int, NB>,NB> t, int a);

int main()
{
    /* déclaration et initialisation  */
    array<array<int, NB>,NB> tab ;
    int x;
    cin >> x;
    for (int i=0;i<NB;i++) {for(int j=0; j<NB; j++) {cin >> tab[i][j];}}

    /* traitement et résultat  */
    tab = produitTableau(tab, x);

    /* résultat */
    for (int i=0; i < NB; i++) {
      for (int j=0; j < NB; j++) {
        cout << tab[i][j] << " ";
      }
    }

  return 0;
}

int calcul(int a, int b)
{
   return a*b;
}

**(here)**

Я ожидаю, что они напишут что-то вроде (я проверяю результат с помощью набора тестовых данных, который хранится в текстовом файле и используется в качестве входных данных):

array<array<int, NB>,NB> produitTableau(array<array<int, NB>,NB> t, int a)
{
    for (int i=0; i < NB; i++) {
      for (int j=0; j < NB; j++) {
        t[i][j] = calcul(t[i][j] , a);
      }
    }

   return t;

}

* массив передается по значению *

Итак, я бы проверил, что общий объем используемых данных превышает определенное значение, например: 10.000 байт.

Может быть, это может быть исполняемый файл ... Я этого не знаю.

Ответы [ 2 ]

2 голосов
/ 30 марта 2019

Что ж, если вы запретите включение чего-либо еще, вы можете адаптировать std::array<T, N> так, чтобы ограничить N до некоторого максимального размера; затем попросите учеников включить этот массив.

Адаптация может быть такой простой, как добавление:

static_assert(N == NB, "For this homework assignment you can only use arrays of NB elements");

внутри класса массива и ранее в файле,

constexpr const size_t NB = 123;

Не забудьте, конечно, не изменять исходный файл массива! Сделайте копию (возможно, даже измените имя, чтобы уточнить, что это пользовательский массив).

2 голосов
/ 30 марта 2019

Я буду реализовывать по частям:

  1. проверка ограничений, установленных источником источника
  2. проверка ограничений размера с помощью параметров компилятора

# 1. проверка ограниченийисправлено исходным кодом #

из @einpoklum advice,

## 1.1 сделайте копию файла заголовка 'array' в 'myArray' и добавьте 'assert' ##

...
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

template<typename _Tp, std::size_t _Nm>
    struct array
    {
       typedef _Tp                        value_type;
      ...
       typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;

       // Support for zero-sized arrays mandatory.
       value_type _M_instance[_Nm ? _Nm : 1];

       static_assert(_Nm == NB, "Check array size...");  <<<<<<<<<<<<

  ... continue...

## 1.2 Определение размера массива в основной программе ##

const unsigned int NB = 10;  <<<<<<<<<<<<<<<<<<<<<<<<w
#include <iostream>
#include "myArray.h" <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
...

Пример 1:

const unsigned int NB = 10;
...
#include "myArray.h"
...
int main()
{
    array<int, 11> tab;
    ...
}

Во время компиляции: Ошибка: статическое утверждение не удалось:Проверить размер массива ...

# 2. проверить ограничения размера с помощью параметров компилятора #

использовать параметр компилятора для обеспечения контроля (ограничить риски неправильного использования: например, массив C илимножественное определение массива, ...

g ++ Параметры компилятора:

  1. -Wlarger-than = x: проверить размер в байтах объекта

  2. -Фрейм больше, чем = x: проверить размер функции [https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#Warning-Options][1] -Фрейм больше, чем = размер байта

  3. -Ошибка: к тurn Предупреждения об ошибках

Пример 1: (-Wlarger-than = 10000)

const int NB = 100;
...
array<array<int, NB>,NB> tab ;

выдает ошибку: ... error: size of tabравно 40000 байт [-Werror = больше-чем =] |

Пример 2: (упрощенный пример) (-Wframe-больше-чем = 10000)

int main()
{
    array<array<int, 100>,100> tab ;
    int x;
    ...
    tab = produitTableau(tab, x);

    return 0;
}

array<array<int, 100>,100> produitTableau(array<array<int, 100>,100> t, int a)
{
...
   return t;
}

выдает ошибку:...error: размер фрейма 80016 байт превышает 10000 байт [-Werror = frame-больше-than =] |

80016 байт = вкладка 10000 * 4 = 40000 байт + параметр, переданный по значению = 40000байты + другие переменные ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...