Код был скопирован и размножен, однако были внесены не все необходимые изменения.
В данном примере в скопированном фрагменте кода необходимо заменить sep
на end
object sep = AttrCollectionPop(kwargs, "sep", " ");
if (sep != null && !(sep is string)) {
throw PythonOps.TypeError(
"sep must be None or str, not {0}",
PythonTypeOps.GetName(sep));
}
object end = AttrCollectionPop(kwargs, "end", "\n");
if (sep != null && !(sep is string)) { // Should be end, not sep
throw PythonOps.TypeError(
"end must be None or str, not {0}",
PythonTypeOps.GetName(end));
}
При переопределении метода не вызван метод базового класса, который должен быть вызван (либо потому, что остальные переопределения его вызывают, либо согласно документации).
После того, как значение было получено при помощи оператора as
, с null
вместо полученного сравнивается исходное значение.
var right = other as PredicateNullness;
if (other != null) // Should be "if (right != null)"
{
if (this.value == right.value)
{
return this;
}
}
Выражение может принадлежать к value-типу, но сравнивается с null.
public static int GetHashCode<T>(T[] a)
{
if (a == null)
return 0;
const int prime = 31;
int hash = 17;
foreach (var item in a)
{
// item is T, and T may be a value type
hash = hash * 23 + (item == null ? 0 : item.GetHashCode());
}
return hash;
}
Внутри условия используется оператор присваивания (=
). Это может быть опечаткой, поскольку оператор равенства (==
) используется внутри условий значительно чаще. Такая диагностика наиболее актуальна в процессе написания кода для ускорения исправления опечаток.
Значение выражения не зависит от значений составляющих его частей или часть выражения может быть опущена без изменения результата.
В данном примере выражение foo[s+6]&0xff
и аналогичные не имеют смысла, поскольку аргумент foo
имеет тип byte[]
, а значение побайтового AND для любого значения a
типа byte
и 0xFF
равно a
.
internal override void write(byte[] foo, int s, int l)
{
.......
int plen=(foo[s+6]&0xff)*256+(foo[s+7]&0xff);
int dlen=(foo[s+8]&0xff)*256+(foo[s+9]&0xff);
.......
}
Блок catch
пуст.
Это само по себе не является ошибкой, но считается антипаттерном.
Интерфейс не содержит ни одного члена. Пустые интерфейсы считаются антипаттерном.
Числа с плавающей точкой сравниваются на точное равенство.
В связи с ошибками округления, вызванными ограниченной точностью чисел с плавающей запятой, результаты операций с ними слегка неточны. Когда неточности невелики, это не является проблемой. Однако ожидания точного равенства при вычислении значений разными способами некорректно. Поэтому необходимо использовать другие способы, например, сравнение разности чисел с допустимой погрешностью.
public static Boolean operator ==(ComplexNumber c1, ComplexNumber c2)
{
bool bEqual = false;
if ((c1._realPart == c2._realPart) &&
(c1._imaginaryPart == c2._imaginaryPart))
bEqual = true;
return bEqual;
}
Имя локальной переменной или параметра метода “закрывает” другую переменную или поле класса с таким же именем.
Использование одинаковых имен не является ошибкой само по себе, однако может приводить к путанице, где какие перменные требуется использовать.
public partial class AddAccountWizardForm : Form
{
...
private Step m_CurrStep = Step.Screen1;
...
private bool ValidateFields(Step m_CurrStep)
{
...
}
...
}
В условном операторе исполняется одинаковый код при разных условиях (например, true- и false- ветви оператора if идентичны).
Выполнение одинаковых инструкций вне зависимости от условия часто свидетельствует об ошибке.
if (negx && negy) {
return new BigInteger(-1, makeTwosComplement(zd));
} else if (negx || negy) {
return new BigInteger(+1, zd);
} else {
return new BigInteger(+1, zd);
}
Несколько методов обладают одинаковой реализацией.
public static object GetCharArrayValue(_Array arr) {
return arr.NativeType.GetValue(arr._memHolder, arr, 0, false);
}
public static object GetWCharArrayValue(_Array arr) {
return arr.NativeType.GetValue(arr._memHolder, arr, 0, false);
}
В switch рассмотрены не все возможные варианты значений аргумента.
public enum TraceEventKind {
FrameEnter,
FrameExit,
ThreadExit,
TracePoint,
Exception,
ExceptionUnwind
}
....
Debugging.TraceEventKind kind = ...
....
switch (kind) {
case Debugging.TraceEventKind.FrameEnter: traceEvent = "call"; break;
case Debugging.TraceEventKind.TracePoint: traceEvent = "line"; break;
case Debugging.TraceEventKind.Exception:
traceEvent = "exception";
object pyException = PythonExceptions.ToPython((Exception)payload);
object pyType = ((IPythonObject)pyException).PythonType;
args = PythonTuple.MakeTuple(pyType, pyException, null);
break;
case Debugging.TraceEventKind.FrameExit:
traceEvent = "return";
args = payload;
break;
}
Статическое поле используется до инициализации.
public static readonly WeakReference WeakMissingConstant = new WeakReference(
StrongMissingConstant);
private static readonly object StrongMissingConstant = new object();
Хотя бы один аргумент вызова ReferenceEquals не является ссылочным типом.
public struct Polynomial<Variable, Expression>
{
...
}
...
Polynomial<BoxedVariable<Variable>, BoxedExpression> pol;
...
Contract.Assume(!object.ReferenceEquals(pol, null));
Бесконечный цикл из-за ошибки при обновлении переменной цикла либо из-за обновления неправильной переменной.
Здесь требуется исправить i > stop
на i < stop
или i += step
на i -= step
for (int i = start; i > stop; i += step) {
pa._data.Append(_data.GetData(i));
}
Здесь требуется исправить i++
на j++
for (int j = 0; j < n; i++) {
Cache.Integers[n - j - 1] = Reader.ReadInt32();
}
Цикл содержит break
или return
без условий, и поэтому исполняется только один раз.
Вместо библиотечных констант используются явно заданные численные значения
В данном случае вместо 6.28318531
следовало использовать 2 * Math.PI
if (Math.Abs(InitialAngle - LastAngle) > 6.28318531) {
...
}
Исключение создается, но оператор throw
пропущен.
try
{
mxRecords = GetMxRecords(domain);
}
catch
{
new Exception("Can't connect to DNS server.");
}
Изменение значения поля, объявленного без оператора volatile
, может произойти только в другом потоке. Условие может быть упрощено.
В данном примере цикл с условием globalState.DoneCount != globalState.Threads.Count
имеет пустое тело, в связи с чем он может быть оптимизирован.
class DictThreadGlobalState {
public int DoneCount;
public List<Thread> Threads = new List<Thread>();
...
}
...
while (globalState.DoneCount != globalState.Threads.Count) {
// wait for threads to get back to start point
}
Код отформатирован таким образом, что при чтении создается неправильное представление о его структуре.
В данном примере из-за неправильной индентации создается впечатление, что return true;
происходит, только если вызов slot.TryGetValue(context, instance, this, out newValue)
вернул true
.
if (dt.TryLookupSlot(context, name, out slot)) {
if (!hasValue || slot.IsSetDescriptor(context, this)) {
if (slot.TryGetValue(context, instance, this, out newValue))
value = newValue;
return true;
}
}
При обращении к статическому полю используется lock на объект, не являющийся статическим.
public sealed class Profiler {
private static int _Index;
private readonly Dictionary<string, int> _counters;
public int GetTickIndex(string name) {
lock (_counters) {
if (!_counters.TryGetValue(name, out index)) {
index = _Index++;
_counters.Add(name, index);
}
...
}
...
}
...
}
Используются устаревшие криптографические алгоритмы.
Значение, возвращенное константным методом, проигнорировано.
try {
...
} catch (Exception e) {
e.ToString();
errors = true;
throw;
}
Непреднамеренная потеря арифметической точности из-за целочисленного деления.
decimal a, b, r;
int n = x.Count();
...
a = (1 / n) * sY - b * (1 / n) * sX;
Целочисленное переполнение может произойти до расширения типа.
internal virtual long BaseRamBytesUsed()
{
return RamUsageEstimator.NUM_BYTES_OBJECT_HEADER +
2 * RamUsageEstimator.NUM_BYTES_OBJECT_REF +
2 * RamUsageEstimator.NUM_BYTES_INT +
2 * RamUsageEstimator.NUM_BYTES_INT +
RamUsageEstimator.NUM_BYTES_FLOAT +
RamUsageEstimator.NUM_BYTES_LONG;
}
В сравнении смешаны целочисленные значения и значения с плавающей точкой.
Объект, реализующий интерфейс IDisposable, возвращается внутри блока using.
public static MemoryStream SerializeToStream(object o)
{
using (var stream = new MemoryStream())
{
Formatter.Serialize(stream, o);
return stream;
}
}
Метод всегда возвращает одно и то же значение.
Переменная присваивается сама себе.
Точка с запятой стоит в неожиданном месте (например, после условия if
до начала предполагаемого блока).
if (!BinaryUpdates.TryGetValue(update.Field, out fieldUpdates)) ;
{
fieldUpdates = new HashMap<Term, BinaryDocValuesUpdate>();
BinaryUpdates[update.Field] = fieldUpdates;
BytesUsed.AddAndGet(BYTES_PER_BINARY_FIELD_ENTRY);
}
Конкатенация строк внутри цикла неэффективна, следует использовать string.Join
или StringBuilder
.
var pluginStates = string.Format(
"plugin states: ({0} in total)", this.otherStates.Length);
if (this.otherStates.Length > 0)
{
foreach (var state in this.otherStates)
{
var str = state.ToString();
pluginStates += Environment.NewLine + str;
}
}
Ошибка форматирования строки.
В данном случае в форматной строке присутствуют индексы от 0 до 5, а аргументов 7.
public override string ToString()
{
return String.Format(
"Preconditions:\n{0}\nPostconditions:\n{1}\nObjectInvariants:\n{2}\n"
"EntryAssumes:{3}\nCalleeAssumes:{4}MayReturnNull{5}",
JoinWithDefaultIfNull("\n", this.PreConditions),
JoinWithDefaultIfNull("\n", this.PostConditions),
JoinWithDefaultIfNull("\n", this.ObjectInvariants),
JoinWithDefaultIfNull("\n", this.NonNullFields),
JoinWithDefaultIfNull("\n", this.EntryAssumes),
JoinWithDefaultIfNull("\n", this.CalleeAssumes),
this.MayReturnNull);
}
Приведение типов выглядит подозрительно.
Аргументы метода переданы в неправильном порядке.
В данном примере перепутаны местами аргументы row и col.
public class RequestWindowChange : Request
{
public void setSize(int row, int col, int wp, int hp)
{
...
}
}
public void setPtySize(int col, int row, int wp, int hp)
{
try
{
RequestWindowChange request=new RequestWindowChange();
request.setSize(col, row, wp, hp);
request.request(session, this);
}
catch(Exception e)
{
throw new JSchException("ChannelShell.setPtySize: "+e.ToString());
}
}
Неправильно использован атрибут [ThreadStatic].
В данном примере инициализация произойдет только в первом потоке.
[Обнаружено в ThreadStatic]
public static List<object> _trace = new List<object>();
В следующем примере атрибут применен не к статическому члену класса.
[Обнаружено в ThreadStatic]
private bool _traceListenerSuspended;
Виртуальный метод класса вызван внутри его конструктора. Это может привести к неконсистентному состоянию, поскольку виртуальный метод, переопределенный в классе-потомке, может использовать еще не проинициализирпованные данные потомка.
В данном примере виртуальный метод Commit
вызывается в конструкторе класса InvariantSubroutine
.
public InvariantSubroutine(
MethodCache<
Local, Parameter, Type, Method, Field, Property,
Event, Attribute, Assembly> methodCache,
Subroutine inherited, Type associatedType)
: base(methodCache)
{
Contract.Requires(methodCache != null);
this.AddSuccessor(this.Entry, "entry", this.Exit);
this.AddBaseInvariant(this.Entry, this.Exit, inherited);
this.Commit();
}
Метод CompareTo не соответствует сигнатуре ‘public int CompareTo(Object)’.
Переменной присвоено значение, не используемое в дальнейшем.
if (format <= Lucene3xSegmentInfoFormat.FORMAT_HAS_VECTORS)
{
int hasVectors = input.ReadByte();
}
Код недостижим, потому что условия, при которых он должен быть исполнен, несовместны.
В данном примере равенство a1 == a2
приводит к выполнению первого условного оператора и выходу из функции. Код, начинающийся с a1 = a1.CloneExpanded();
, недостижим.
public static Automaton Union(Automaton a1, Automaton a2)
{
if ((a1.IsSingleton && a2.IsSingleton && a1.singleton.Equals(a2.singleton)) || a1 == a2)
{
return a1.CloneIfRequired();
}
if (a1 == a2)
{
a1 = a1.CloneExpanded();
a2 = a2.CloneExpanded();
}
...
}
Результат выражения равен константе.
В данном примере значение newSize
имеет тип int
, а значит, не может превышать int.MaxValue
int newSize = Size + otherUpdates.Size;
if (newSize > int.MaxValue)
{
throw new InvalidOperationException(
"cannot support more than Integer.MAX_VALUE doc/value entries; size=" +
Size + " other.size=" + otherUpdates.Size);
}
Переменная была сравнена со значением null
(что означает, что она может принимать это значение) и после использована без проверки.
В данном примере в случае, если expected == null && actual != null
, будет выброшено исключение NullReferenceException
static void AreEqual<T>(T expected, T actual) {
if (expected == null && actual == null) return;
if (!expected.Equals(actual)) {
Console.WriteLine("Expected: {0} Got: {1} from {2}",
expected, actual, new StackTrace(true));
throw new Exception();
}
}
Использование переменной, которой присвоили значение null
, и существуют пути исполнения программы, по которым это значение не было перезаписано.
В данном примере NullReferenceException
будет выкинуто, если tree2
окажется равным null
или не реализующим интерфейс IAssemblyReference
.
IAssemblyReference ar = null;
try {
var tree2 = transformer.Visit(compilationUnitDeclaration);
ar = tree2 as IAssemblyReference;
} catch (ConverterException e) {
exceptionMessage = e.Message;
}
if (exceptionMessage != null) {
yield return Tuple.Create(
exceptionMessage, compilationUnitDeclaration.GetFirstToken().Span);
yield break;
}
var unit = ar;
this.host.RegisterUnit(unit.ResolvedUnit);
Проверка переменной на null произведена после ее использования.
В данном примере аргумент list
проверяется на null
позже, чем используется в (toIndex > list.Count)
.
public SubList(IList<T> list, int fromIndex, int toIndex)
{
if (fromIndex < 0)
throw new ArgumentOutOfRangeException("fromIndex");
if (toIndex > list.Count)
throw new ArgumentOutOfRangeException("toIndex");
if (toIndex < fromIndex)
throw new ArgumentOutOfRangeException("toIndex");
if (list == null)
throw new ArgumentNullException("list");
this.list = list;
this.fromIndex = fromIndex;
this.toIndex = toIndex;
}
Возможность взаимной блокировки.
В данном синтетическом примере функции Foo
и Bar
, вызванные одновременно в разных потоках, заблокируют одна другую.
void Foo() {
lock(a)
lock(b)
Baz1();
}
void Bar() {
lock(b)
lock(a)
Baz2();
}
Переменная была проверена на принадлежность типу (что означает, что она может ему не принадлежать) и после приведена к нему без проверки.
В примере вначале происходит проверка на то, что task.Result
не принадлежит типу ResultResponse
, после чего сразу происходит приведение к этому типу. В данном случае вместо оператора ||
использован оператор &&
.
if (!(task.Result is ResultResponse) &&
!(((ResultResponse)task.Result).Output is OutputRows))
{
throw new DriverInternalError("Expected rows " + task.Result);
}
Обнаружено в C# Driver for Apache Cassandra
У объекта, реализующего интерфейс IDisposable, не вызывается метод Dispose().
В данном примере ресурс bos не освобождается.
public static byte[] Compress(
byte[] value, int offset, int length, int compressionLevel)
{
var bos = new ByteArrayOutputStream(length);
Deflater compressor = SharpZipLib.CreateDeflater();
try
{
compressor.SetLevel(compressionLevel);
compressor.SetInput(value, offset, length);
compressor.Finish();
var buf = new byte[1024];
while (!compressor.IsFinished)
{
int count = compressor.Deflate(buf);
bos.Write(buf, 0, count);
}
}
finally
{
}
return bos.ToArray();
}
В следующем примере вызов метода WriteLine
может выкинуть IOException
, и если это произойдет, ресурс file
не будет освобожден.
var file = new StreamWriter(Path.Combine(cwd, writeBatchFile + ".bat"));
file.WriteLine("\"{0}\" {1} %1 %2 %3 %4 %5", i.FileName, i.Arguments);
file.Close();
К переменной, к которой в основном обращаются под lock-ом, произошло обращение вне lock-а.