Reputation: 217
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
Reputation: 217
I will implement to parts :
from @einpoklum advice,
...
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...
const unsigned int NB = 10; <<<<<<<<<<<<<<<<<<<<<<<<w
#include <iostream>
#include "myArray.h" <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
...
const unsigned int NB = 10;
...
#include "myArray.h"
...
int main()
{
array<int, 11> tab;
...
}
At compile time : error: static assertion failed: Check array size...
use compiler option to enforce control (limit the risks of misuse : C array for example, or multiple definition of array, ...
g++ compiler options :
-Wlarger-than=x : check size in bytes of an object
-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
-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
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