有没有办法限制C ++编译时的数据大小并产生编译错误?

时间:2019-03-30 10:12:07

标签: c++ c++11

我已经构建了一个工具,使学生能够在线(在受保护的环境中)编译和测试自己的C ++代码。

我想在编译时检查程序中的数据大小总量是否超过一定大小,如果确实不超过一定大小,则会产生编译错误。

(立即目标:限制c ++ std :: 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字节。

可能是exe文件...我不知道。

2 个答案:

答案 0 :(得分:2)

我将实现部分:

  1. 检查由来源确定的约束
  2. 使用编译器选项检查大小限制

#1.检查由源代码源#

修复的约束

来自@einpoklum建议,

## 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. -Wframe-larger-than = x:检查函数的大小 [https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#Warning-Options][1] -Wframe-larger-than =字节大小

  3. -Werror:将警告变为错误

示例1:(-Wlarger-than = 10000)

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

产生错误:... error:'tab'的大小为40000字节[-Werror = larger-than =] |

示例2 :(简化示例)(-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;
}

产生错误:...错误:80016字节的帧大小大于10000字节[-Werror = frame-larger-than =] |

80016字节=  制表符10000 * 4 = 40000字节  +通过值传递的参数= 40000字节  +其他变量...

答案 1 :(得分:2)

好吧,如果您阻止包含其他任何内容,则可以改编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;

请记住,当然不要更改原始数组文件!进行复制(也许甚至更改名称以说明它是自定义数组)。