【问题标题】:Does MISRA C++ rule 7-1-1 affect references?MISRA C++ 规则 7-1-1 会影响引用吗?
【发布时间】:2017-02-22 10:10:23
【问题描述】:

规则 7-1-1(必需)未修改的变量应为 const 限定

如果一个变量不需要修改,那么它应该是 使用 const 限定条件声明,使其不能被修改。一种 非参数变量将需要在 声明点。此外,未来的维护不能意外 修改值。

void b ( int32_t * );
int32_t f (       int32_t * p1,                 // Non-compliant
                  int32_t * const p2,           // Compliant
                  int32_t * const p3 )          // Compliant
{
     *p1 = 10;
     *p2 = 10;
     b( p3 );
     int32_t i = 0;                             // Non-compliant
     return i;
}

标准中包含的示例侧重于指针。该规则要求所有满足条件的指针都是const,例如int * const。如果我理解正确,它不需要需要指针和引用来指向const 对象,例如const int *const int &。事实上,它被另一条规则所涵盖(但仅限于参数!):

Rule 7-1-2 (Required) 如果对应的对象没有被修改,函数中的指针或引用参数应声明为指向 const 的指针或对 const 的引用

那么,规则 7-1-1 是否适用于引用?引用在创建后无法重新绑定,因此应将其视为const 指针。因此,所有引用都应自动遵守规则 7-1-1。

编辑(基于 Lightness Races in OrbitRichard CrittenPeter 的 cmets 以及我的实验): 或者该规则是否适用于引用对象的类型在参考的情况下?我的意思是const int &int & 类似于const intint? 我之所以问,是因为我的 MISRA C++ 检查器不断报告引用的违规行为……其行为示例:

class A
{
    int property;
public:
    A(int param) : property(param) {}     // violation: should be: const int param
    int get_property() const { return property; }
    void set_property(int param) { property = param; }  // violation: should be: const int param
};

class ConstA
{
    const int property;
public:
    ConstA(int param) : property(param) {}  // violation: should be: const int param
    int get_property() const { return property; }
    // setter not allowed
};

void example1()
{
    const A const_obj_A(1);
    A nonconst_obj_A(2);
    ConstA nonconst_obj_constA(3);      // OK: used to create a non-const reference
    const A& const_ref_A = nonconst_obj_A;
    A& nonconst_ref_A = nonconst_obj_A; // OK: setter called
    nonconst_ref_A.set_property(4);
    ConstA& const_ref_constA = nonconst_obj_constA; // violation: no modification
    // In fact, it seems to be impossible to make
    // a non-violating ConstA& declaration.
    // The only chance is to make another non-const reference
    // but the last declaration in the chain will still violate.
}

void example2()
{
    const A const_obj_A(1);
    A nonconst_obj_A(2);
    ConstA nonconst_obj_constA(3);      // violation: used only in const reference
    const A& const_ref_A = nonconst_obj_A;
    A& nonconst_ref_A = nonconst_obj_A; // violation: no modification using the ref.
    const ConstA& const_ref_constA = nonconst_obj_constA;
}

【问题讨论】:

  • 它说“变量”,所以我的看法是如果可以引用 const 它应该是。
  • 如果您的问题是关于参考的,请提供相关代码和参考。 ...恕我直言,这条规则非常薄弱。

标签: c++ reference misra


【解决方案1】:

不,7-1-1 不适用于引用。

int32_t & const p2 形式的声明是无稽之谈。

引用的唯一有意义的const 限定是const int32_t &p2 或等效的int32_t const &p2 形式。然后,7-1-2 完全涵盖了对这些表格的需求。

Misra 7-1-1 不需要应用于此类引用,因为 Misra 的理念是指定语言标准未指定的约束,而不是重申语言中已经指定的约束(并由编译器强制执行)。 Misra 7-1-1 需要声明一个变量(例如,int32_t 类型),如果它不会被修改 - 例如引用示例中的 i。在标准 C++ 中,不可能创建对该变量的非 const 引用 - 除非使用类型转换(也称为“强制转换”)来删除 constness。 Misra 规则 5-2-5 要求不得使用此类演员表。

【讨论】:

  • 几乎但不完全 - 7-1-2 仅涵盖参数,除非存在 OP 未引用的文本
  • @LightnessRacesinOrbit 你是对的。规则 7-1-2 说:这个规则导致函数接口的定义更加精确。 所以它不会影响局部变量。这使得 7-1-1 更加成问题……
  • @Melebius:更奇怪的是,它继续声明这意味着指针应该是const,而不是指针本身。这真是令人费解。就像 Google C++ 风格指南一样,我对那些坚持遵守 MISRA“规则”的人提出异议,就好像它们是法律一样。或者,好吧,好像他们是明智的。
  • @LightnessRacesinOrbit 感谢 cmets,我已经完善了这个问题。
  • Misra 通常不会说明语言中的要求。如果一个对象是const,如果不打算修改它,则 7-1-1 将需要它,那么在 C++ 中不可能创建对它的非const 引用,除非类型转换(又名“ cast") 用于删除const 限定符。 C++ 编译器会诊断错误。虽然可以通过类型转换来强迫编译器提交,但另一个 Misra 规则 (5-2-5) 要求不应使用此类强制转换。我很快就会对此进行编辑并添加评论。
【解决方案2】:

C++ 指针和引用之间存在显着的语义差异:引用不是对象(变量)。

这只是对象别名。因此,严格意义上的 7-1-1 不适用于引用。

【讨论】:

  • 而且,即使它是相关的,它也会隐含地应用,因为问题已经说明了。所以是的,看不到 7-1-1 是如何应用的。 7-2-2 是相关规则,但奇怪的是,仅适用于函数参数
  • 同意,规则有点模糊。 7-1-1 是关于变量的,但示例描述了函数参数。目前尚不清楚“变量”一词实际上是否包含参数以及在 7-1-2 中区分它们的目的是什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-13
  • 1970-01-01
  • 2015-12-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多