1月にPVS-StudioELKIがチェックされた方法

新年が昨日だけで、1月の半分以上が過ぎていることに気づかなかったと思われる場合は、この間ずっと、保守しているコードの微妙なバグを探すのに忙しくしています。それはまた、私たちの記事があなたのためだけであることを意味します。私たちPVS-Studioは、ELKIオープンソースプロジェクトをチェックして、コードで検出できるエラー、エラーを巧みに隠す方法、および対処方法を示しました。







0111_ELKI_ru / image1.png







ELKI-このライブラリは何ですか?



ELKI Environment for Developing KDD-Applications Supported by Index-Structures. Java . – , , -. , . . .







, , , , . , ELKI, . , . , .







AGPL , , . . . .









ELKI 2 630 java, 186 444 , . open source .







. , . ! 10 , , , .









V6001 There are identical sub-expressions 'bounds[j + 1]' to the left and to the right of the '!=' operator. CLIQUEUnit.java(252)







private boolean checkDimensions(CLIQUEUnit other, int e) {
    for(int i = 0, j = 0; i < e; i++, j += 2) {
        if (dims[i] != other.dims[i]
            || bounds[j] != other.bounds[j]
            || bounds[j + 1] != bounds[j + 1]) {
          return false;
        }
    }
    return true;
}
      
      





if checkDimensions bounds[j + 1] . , , . checkDimensions true , .







if :







bounds[j + 1] != other.bounds[j + 1]
      
      







V6022 Parameter 'updates' is not used inside constructor body. DataStoreEvent.java(60)







V6022 Parameter 'removals' is not used inside constructor body. DataStoreEvent.java(60)







public DataStoreEvent(DBIDs inserts, DBIDs removals, DBIDs updates) {
    super();
    this.inserts = inserts;
    this.removals = inserts;
    this.updates = inserts;
}
      
      





. DataStoreEvent , . , , , .







, DataStoreEvent , , .







public static DataStoreEvent insertionEvent(DBIDs inserts) {
  return new DataStoreEvent(inserts, DBIDUtil.EMPTYDBIDS, DBIDUtil.EMPTYDBIDS);
}

public static DataStoreEvent removalEvent(DBIDs removals) {
  return new DataStoreEvent(DBIDUtil.EMPTYDBIDS, removals, DBIDUtil.EMPTYDBIDS);
}

public static DataStoreEvent updateEvent(DBIDs updates) {
  return new DataStoreEvent(DBIDUtil.EMPTYDBIDS, DBIDUtil.EMPTYDBIDS, updates);
}
      
      





- .







:







this.inserts = inserts;
this.removals = removals;
this.updates = updates;
      
      







V6012 The '?:' operator, regardless of its conditional expression, always returns one and the same value '0.5'. ClusterHullVisualization.java(173), ClusterHullVisualization.java(173)







public void fullRedraw() {
    ....
    boolean flat = (clusters.size() == topc.size());
    // Heuristic value for transparency:
    double baseopacity = flat ? 0.5 : 0.5;
    ....
}
      
      





baseopacity 0.5 , flat. , , - .







. , , . , 90 – . , .









V6025 Index '1' is out of bounds. GeneratorStatic.java(104)







@Override
public double[] computeMean() {
    // Not supported except for singletons.
    return points.size() == 1 ? points.get(1) : null;
}
      
      





computeMean , points , , , … 1. , IndexOutOfBoundsException .







:







return points.size() == 1 ? points.get(0) : null;
      
      





?



V6020 Divide by zero. The range of the 'referenceSetSize' denominator values includes zero. PreDeConNeighborPredicate.java(138)







protected PreDeConModel computeLocalModel(DoubleDBIDList neighbors, ....) {
    final int referenceSetSize = neighbors.size();
    ....
    // Shouldn't happen:
    if(referenceSetSize < 0) {
        LOG.warning("Empty reference set – 
            should at least include the query point!");
        return new PreDeConModel(Integer.MAX_VALUE, DBIDUtil.EMPTYDBIDS);
    }
    ....
    for(int d = 0; d < dim; d++) {
        s[d] /= referenceSetSize;
        mvVar.put(s[d]);
    }
    ....
}
      
      





, . . . .







neighbors, computeLocalModel. neighbors if, , . .. referenceSetSize < 0 , set – . , referenceSetSize == 0.







neighbors, for . , .









V6062 Possible infinite recursion inside the 'setInitialMeans' method. Predefined.java(65), Predefined.java(66)







public void setInitialMeans(List<double[]> initialMeans) {
    this.setInitialMeans(initialMeans);
}
      
      





. , . , - :







this.setInitialMeans(initialMeans.toArray(new double[0][0]));
      
      





, , , , - . , , :







public void setInitialMeans(double[][] initialMeans) {
    double[][] vecs = initialMeans.clone(); // TODO: deep copy?
    this.initialMeans = vecs;
}
      
      







V6094 The expression was implicitly cast from 'int' type to 'double' type. Consider utilizing an explicit type cast to avoid the loss of a fractional part. An example: double A = (double)(X) / Y;. ProbabilityWeightedMoments.java(130)







public static <A> double[] alphaBetaPWM(...., final int nmom) {
    final int n = adapter.size(data);
    final double[] xmom = new double[nmom << 1];
    double aweight = 1. / n, bweight = aweight;
    for(int i = 0; i < n; i++) {
        ....
        for(int j = 1, k = 2; j < nmom; j++, k += 2) {
            xmom[k + 1] += val * (aweight *= (n - i - j + 1) / (n - j + 1));
            xmom[k + 1] += val * (bweight *= (i - j + 1) / (n - j + 1));
        }
    }
    return xmom;
}
      
      





for (n — i — j + 1) / (n — j + 1) int double. : , . , , , xmom double. , , (n – i – j + 1) / (n – j + 1). , n – j + 1 x. : (x – i) / x. 0 , . . . n , , .







, , double:







xmom[k + 1] += val * (aweight *= (double) (n - i - j + 1) / (n - j + 1));
xmom[k + 1] += val * (bweight *= (double) (i - j + 1) / (n - j + 1));
      
      







V6079 Value of the 'splitpoint' variable is checked after use. Potential logical error is present. KernelDensityFittingTest.java(97), KernelDensityFittingTest.java(97)







public final void testFitDoubleArray() throws IOException {
    ....
    int splitpoint = 0;
    while(fulldata[splitpoint] < splitval && splitpoint < fulldata.length) {
        splitpoint++;
    }
    ....
}
      
      





while fulldata splitpoint splitval, , splitpoint , . while , .









V6019 Unreachable code detected. It is possible that an error is present. Tokenizer.java(172)







V6007 Expression 'c != '\n'' is always true. Tokenizer.java(169)







public String getStrippedSubstring() {
    int sstart = start, ssend = end;
    while(sstart < ssend) {
        char c = input.charAt(sstart);
        if(c != ' ' || c != '\n' || c != '\r' || c != '\t') {
            break;
        }
        ++sstart;
    }
    ....
}
      
      





, . V6019 : ++sstart, V6007 if, .







if ? . : c != ' ', c != '\n', c != '\r', c != '\t'. - . false, true, - || () if . ifbreak, while, sstart . V6019 .







, - :







if(c != ' ' && c != '\n' && c != '\r' && c != '\t')
      
      





,



V6009 Function 'equals' receives an odd argument. An object 'other.similarityFunction' is used as an argument to its own method. AbstractSimilarityAdapter.java(91)







@Override
public boolean equals(Object obj) {
    if(obj == null) {
        return false;
    }

    if(!this.getClass().equals(obj.getClass())) {
        return false;
    }

    AbstractSimilarityAdapter<?> other = (AbstractSimilarityAdapter<?>) obj;
    return other.similarityFunction.equals(other.similarityFunction);
}
      
      





equals AbstractSimilarityAdapter. , , , equals . , , equals . .







:







return this.similarityFunction.equals(other.similarityFunction);
      
      





, , Java. ' '. , , , .









, . — , – . – , . – , . , .







– . , review , unit . , , .









, , , . . , ?







, , . , , , , . , . . , .







, , , :







  1. Trans-Proteomic Pipeline (TPP).
  2. - .
  3. ?
  4. ROOT — .
  5. NCBI Genome Workbench: .



All Articles