Patrick Dezecache
Patrick Dezecache

Reputation: 217

Is there a way to limit data size at C++ compile time and produce a compile error?

I have build a tool that enable students to compile and test their own C++ code on line (on a protected environment).

I would like to check, at compile time, that the total amount of data size in a program does not exceed a certain size, and produce a compile error if it does.

(immediate goal : limit c++ std::array size )

I did not find information on the Web.

My compile chain is :

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

Thanks for help.

EDIT 1

I give them a skeleton, and they have to complete where (here) is specified :

"Complete the program (here) with the definition of 'produitTableau' that get an a 2 dimensional array of integer et an integer and that apply 'calcul' function to each of its vallues and that returns the modified array." (in french...)

#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)**

I expect them to write something like (I check the result with a test data set that is store in a text file and that is used as input data) :

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;

}

* the array is passed by value *

So I would check that the total amount of data used is thess than a certain value, for example : 10.000 bytes.

May be it could be the exe file...I don't know that.

Upvotes: 2

Views: 732

Answers (2)

Patrick Dezecache
Patrick Dezecache

Reputation: 217

I will implement to parts :

  1. check contraints fixed by source source
  2. check size limits using compiler options

# 1. check contraints fixed by source source #

from @einpoklum advice,

## 1.1 make of copy of 'array' header file to 'myArray' and add '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 Define array size in the main program ##

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

Example 1 :

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

At compile time : error: static assertion failed: Check array size...

# 2. check size limits using compiler options #

use compiler option to enforce control (limit the risks of misuse : C array for example, or multiple definition of array, ...

g++ compiler options :

  1. -Wlarger-than=x : check size in bytes of an object

  2. -Wframe-larger-than=x : check size of a function [https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#Warning-Options][1] -Wframe-larger-than=byte-size

  3. -Werror : to turn Warnings to Errors

Example 1 : ( -Wlarger-than=10000 )

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

produces the error : ...error: size of 'tab' is 40000 bytes [-Werror=larger-than=]|

Example 2 : (simplified example) ( -Wframe-larger-than=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;
}

produces the error : ...error: the frame size of 80016 bytes is larger than 10000 bytes [-Werror=frame-larger-than=]|

80016 bytes = tab 10000*4=40000 bytes + parameter passed by value = 40000 bytes + other variables...

Upvotes: 2

einpoklum
einpoklum

Reputation: 131435

Well, if you prevent includes of anything else, you could adapt std::array<T, N> so as to limit N to some maximum size; then make the students include that array instead.

The adaptation might be as simple as adding:

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

within the array class, and earlier in the file,

constexpr const size_t NB = 123;

Remember not to change the original array file of course! Make a copy (perhaps even change the name to clarify it's a custom array).

Upvotes: 2

Related Questions