少し前まで、従業員の1人が私たちのチームを去り、組み込みシステムに関連するソフトウェアの開発に従事している会社に参加しました。 それについて特別なことは何もありません、いつでもどこでも、誰かが去り、誰かが来ます。 それはすべて、パンの数、利便性、好みに依存します。 別のことは興味深いです。 新しい職場でのコードの状態を心配している男性は、その結果、この共同記事になりました。 静的コード分析とは何かを知っていると、「プログラムする」ことは困難です。
自然保護区
世界では興味深い状況が生じているように思えます。 プログラミング部門が、組織の活動の主な領域と直接的な関係を持たない小さな支援要素に過ぎない場合はどうなりますか? 予備があります。 組織の範囲は、arbitrarily意的に重要かつ責任を負うことができます(医療、軍事機器)。 とにかく、新しいアイデアが設定され、10年前の技術が使用される沼地が形成されます。
原子力発電所のプログラミング部門で働いている一人の人とのやり取りからいくつか触れてみましょう。
そして彼は私に答えます:なぜgitが必要なのですか? 見て、すべてが私のノートに書き留められています。
...
バージョン管理はありますか?
2人がgitを使用しています。 オフィスの残りの部分は、せいぜい番号の付いたzip番号です。 zipについてですが、私は1人しか確信していません。
怖がらないでください。 NPPで開発されたソフトウェアは異なりますが、ハードウェア保護をキャンセルした人はいませんでした。 この部門は、統計データの収集と処理を行っています。 しかし、それでも、水浸しの傾向ははっきりと見えます。 なぜこれが起こるのかわかりませんが、そうなっています。 さらに、会社が大きくなればなるほど、この効果はより強く現れます。
大規模組織の停滞は国際的な現象であることを強調したいと思います。 外国人にとっては、物事はまったく同じです。 私は長い間検索しましたが、非常に適切な記事を見つけることができませんでした。 名前も覚えていません。 誰かが私に言ったら、リンクを追加します。 その中で、プログラマーは、彼が1つの軍事部門でどのように働いたかの物語を語ります。 部門は当然ひどく秘密で、ひどく官僚的でした。 とても秘密で官僚的なため、数か月間、彼らは彼にコンピューターを使って仕事をする権利を与えることに同意できませんでした。 その結果、彼は(コンパイルせずに)メモ帳でプログラムを作成しました。 そして、彼は非能率のために解雇されました。
フォレスター
元従業員に戻ります。 新しい仕事に着くと、彼は小さなカルチャーショックを経験しました。 静的解析ツールに悩まされた後、コンパイラの警告さえ無視されるのを見るのは難しいです。 一般に、それは孤立した世界のようであり、彼らは独自の規範に従ってプログラミングし、しばしば独自の用語を使用します。 彼の物語のほとんどは、「固定ポインタ」というフレーズが好きでした。 ハードウェアへのトレースされた近接。
チームの中で、コードの品質と信頼性を重視する資格のあるスペシャリストに成長したことを誇りに思います。 彼は現在の状況を黙って受け入れなかったが、それを修正しようとしている。
最初に、彼は次のことを行いました。 彼はコンパイラの警告を読みました。 その後、彼はCppcheckを使用してプロジェクトをテストしました 。 修正に加えて、彼は典型的なエラーを防ぐことを考えました。
最初のステップの1つは、生成されたコードの品質を向上させることを目的としたドキュメントの準備でした。 別のステップは、開発プロセスへの静的コードアナライザーの導入です。 PVS-Studioはこれまでのところ問題外です。 1つはLinuxです。 第二に、そのような組織へのソフトウェアの販売は容易ではありません。 これまでのところ、選択はCppcheckにかかっています。 これは、静的分析の方法論を初めて知った人にとって非常に優れたツールです。
彼が作成した「プログラムを書かない方法」という文書に精通することを提案します。 多くのポイントが船長証拠のスタイルで書かれているように見えるかもしれません。 しかし、これらは彼が防止しようとしている本当の問題です。
プログラムを書かない方法
アイテムN1
コンパイラの警告を無視します。 リストが大きいため、新しく作成されたコードに現れた実際のソフトウェアエラーを簡単に見逃してしまう可能性があります。 したがって、すべての警告を削除する必要があります。
アイテムN2
「if」演算子の条件では、値はチェックされませんが、割り当ては次のようになります。
if (numb_numbc[i] = -1) { }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    
      , . :
if (numb_numbc[i] == -1) { }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      N3
«using namespace std;» , , . , .
N4
:
unsigned int BufPos;
std::vector<int> ba;
....
if (BufPos * 2 < ba.size() - 1) { }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    
      , :
- ;
 - ;
 - INT_MAX ( );
 - int //… unsigned , unsigned ( );
 
N5
. :
void foo(std::string &str)
{
  if (str = "1234")
  {
  }
}
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    
      '=' '=='. 'str' , .
N6
, :
har TypeValue [4];
...
if (TypeValue == "S") {}
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    
      TypeValue «S» 'false'. 'strcmp' 'strncmp'.
N7
:
memset(prot.ID, 0, sizeof(prot.ID) + 1);
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    
      , 'prot.ID' .
sizeof() strlen(). sizeof() . strlen() ( ).
N8
:
struct myStruct
{
  float x, y, h;
};
myStruct *ptr;
 ....
memset(ptr, 0, sizeof(ptr));
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    
      '*ptr', N (N — ). :
myStruct *ptr;
 ....
memset(ptr, 0, sizeof(*ptr));
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      N9
:
if (0 < L < 2 * M_PI) { }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    
      , , 'true' 'false' . . :
 if (0 < L && L < 2 * M_PI) { }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      N10
unsigned int K;
....
if (K < 0) { }
...
if (K == -1) { }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    
      .
N11
, . :
short s;
...
If (s==0xaaaa) { }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    
      .
N12
'new' 'malloc' 'delete'/'free' . , :
void foo()
{
  std::vector<int> *v1 = new std::vector<int>;
  std::vector<int> v2;
  v2->push_back(*v1);
  ...
}
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    
      , 'v2' 'std::vector<int>'. - , 'int'. , 'v1', . , , 'delete v1' . .
'v1' , :
void foo()
{
  std::vector<int> v1;
  std::vector<int> v2;
  v2->push_back(v1[0]);
  ...
}
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      N13
'new[]', 'delete'. — 'new', 'delete[]'. , : "delete, new[] C++ ".
N14
:
int sum;
...
for (int i = 0; i < 10; i++)
{
  sum++;
}
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    
      /++ . , . . .
N15
:
char* CreateName()
{
  char FileName[100];
  ...
  return FileName;
}
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    
      'FileName' , , .
N16
, '-1' . , , , . .
N17
, Unit-.
N18
. :
D = ns_vsk.bit.D_PN_ml + (int)(ns_vsk.bit.D_PN_st) << 16;
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    
      , . " /++ ". , — , . :
#define A 1
#define B 2
#define TYPE A | B
if (type & TYPE) { }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    
      , TYPE . 'type & A', '(type & A ) | B'. — .
N19
:
int mas[3];
mas[0] = 1;
mas[1] = 2;
mas[2] = 3;
mas[3] = 4;
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    
      'mas[3] = 4;' , 'int mas[N]' [0...N-1].
N20
'&&' '||'. '&&' . :
if (A || B && C) { }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    
      . , -. .
N21
:
void foo(int *a, int b)
{
  If (b == 10)
  {
    *a = 10;
  }
  else
  {
    a = new int;
  }
}
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    
      'a' , :
void foo(int *&a, int b) {....}
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    
      :
void foo(int **a, int b) {....}
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      :
- , . ++. . ;
 - ++. 101 . , ;
 - . . ;
 - ++. . ;
 - C++. 50 . .
 
. , - , . .
, . , . . , « », . , , , , .
. ( : TDD, , , , ...), 10 //( - ). , . - - .
? PVS-Studio. . :)