メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

CERT C++: DCL52-CPP

const または volatile で参照型を修飾しない

説明

ルール定義

const または volatile で参照型を修飾しないようにします。1

Polyspace 実装

ルール チェッカーは以下の問題をチェックします。

  • const 修飾子または volatile 修飾子付きの C++ の参照型

  • const 修飾子付きの型と後続の変更への C++ 参照

すべて展開する

問題

const 修飾子付きの参照型は、参照型の変数が、次のように、const 修飾子または volatile 修飾子で宣言された場合に発生します。

char &const c;

リスク

C++14 規格では、const 修飾子または volatile 修飾子付きの参照は適格ではありません (ただし、typedef を通じて導入された場合は無視されます)。たとえば、ある変数への参照を別の変数への参照に使用することはできません。そのため、参照型の変数に対して const 修飾子を使用する必要はありません。

これらの修飾子の使用は多くの場合、コーディング エラーを示します。たとえば、次のように const 修飾子付きの型への参照を宣言しようとして

char const &c;
代わりに const 修飾子付きの参照を宣言したとします。
char &const c;
コンパイラがこのエラーを検出しない場合、予期しない結果が生じる可能性があります。たとえば、c が変更されないことを想定しているにもかかわらず、c の値が宣言時の値と異なる可能性があります。

修正方法

const 修飾子または volatile 修飾子が適切に配置されているかどうかを確認します。たとえば、const 修飾子付きの型への参照を意図して次のように入力しているかどうかを確認します。

char &const c;
以下のようにはしません。
char const &c;
修飾子が適切に配置されていない場合、エラーを修正します。const 修飾子または volatile 修飾子を & 演算子の前に配置します。そうでない場合、冗長な修飾子を削除します。

例 – const 修飾子付きの参照型
int func (int &const iRef) { //Noncompliant
    iRef++;
    return iRef%2;
}

この例では、iRefconst 修飾子付きの参照型です。iRef は別の変数を参照できないので、const 修飾子は冗長です。

修正 — const 修飾子を削除

冗長な const 修飾子を削除します。iReffunc 内で変更されるので、const 修飾子付きの変数への参照を意図していません。const 修飾子を & の前に移動すると、コンパイル エラーが発生します。

int func (int &iRef) {
    iRef++;
    return iRef%2;
}
修正 — 修飾子 const の配置を修正

func での iRef の変更が確認されない場合は、iRefconst 修飾子付きの変数への参照として宣言します。const 修飾子を & 演算子の前に配置します。iReffunc 内で変更していないことを確認します。

int func (int const &iRef) {
    return (iRef+1)%2;
}
問題

この欠陥は、const 修飾型を参照する変数が宣言後に変更された場合に発生します。

たとえば、次の例で、refValconst int & 型ですが、その値が後続のステートメントで変更されています。

using constIntRefType = const int &;
void func(constIntRefType refVal, int val){
   ...
   refVal = val; //refVal is modified
   ...
}

リスク

参照型に対する const 修飾子は、宣言時にその型の変数が初期化され、それ以降変更しないことを意味します。

コンパイラは const 修飾子付きの型への参照の変更をコンパイル エラーと見なす可能性があります。コンパイラがエラーを検出しなかった場合の動作は未定義です。Polyspace® は、コンパイラ エラーに関係なく、この欠陥にフラグを設定します。

修正方法

const 修飾子付きの参照型の変更を避けます。変更が必要な場合は、参照型の宣言から const 修飾子を削除します。

例 – const 修飾子付きの参照型の変更
typedef const int cint;           
typedef cint& ref_to_cint;       

void func(ref_to_cint refVal, int initVal){ //Noncompliant
   refVal = initVal;
}

この例では、ref_to_cintconst 修飾子付きの型への参照です。ref_to_cint 型の変数 refVal は、func が呼び出されるときに初期化され、以降は変更されないと想定されています。変更は const 修飾子による暗黙的なコントラクトに違反します。refValconst 参照であるためにコンパイルは失敗する可能性があります。Polyspace はこの違反にフラグを設定します。

修正 — const 修飾子付きの参照型の変更を回避

考えられる 1 つの修正方法として、参照型の宣言で const の使用を避けます。

typedef int& ref_to_int;       

void func(ref_to_int refVal, int initVal){
   refVal = initVal;
}

チェック情報

グループ: 01.宣言と初期化 (DCL)

バージョン履歴

R2019a で導入


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.