Jika menurut Anda Tahun Baru baru datang kemarin, dan Anda tidak memperhatikan sudah lebih dari setengah bulan Januari telah berlalu, maka selama ini Anda sibuk mencari bug halus dalam kode yang Anda pertahankan. Itu juga berarti bahwa artikel kami hanya untuk Anda. Kami, PVS-Studio, memeriksa proyek sumber terbuka ELKI untuk menunjukkan kepada Anda kesalahan apa yang dapat ditemukan dalam kode, seberapa cerdiknya mereka bersembunyi di sana, dan bagaimana Anda dapat mengatasinya.

ELKI - perpustakaan apa ini?
ELKI Environment for Developing KDD-Applications Supported by Index-Structures. Java . – , , -. , . . .
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 . if – break, 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);
, . — , – . – , . – , . , .
, , , . . , ?
, , . , , , , . , . . , .
, , , :