OCLint 0.10.2 包含67条规则
if (a | b)
)if (!obj1)
)if (a == NULL
)x % 2 == 1
对于负数不起作用、使用 x & 1 == 1
or x % 2 != 0
代替) if (x) // these two if statements can be
{
if (y) // combined to if (x && y)
{
foo();
}
}`
int a = 1== 1 ? 1:0
)if(true)
)if(a = 1) return 1; return 2;//deadcode
)if(!!a)
)goto a
)for (int i = 0; i < a; i++) {
for (int j = 0; j < a; i++) { // references both 'i' and 'j'
}
}
if ([obj1 isEqualTo:obj2] && obj1)
) if (a->bar(b) && a != NULL)
)int b = -(+(!(~1)));
)@try
{
foo();
}
@catch(id ex)
{
bar();
}
@finally
{
return; // this can discard exceptions.
}
@try {;}
@catch(id ex) {;}
@finally {
id ex1;
@throw ex1; // this throws an exception
NSException *ex2 = [NSException new];
[ex2 raise]; // this throws an exception, too
}
layoutSubViews
)@interface A : NSObject
- (void)foo __attribute__((annotate("oclint:enforce[protected method]")));
@end
@interface B : NSObject
@property (strong, nonatomic) A* a;
@end
@implementation B
- (void)bar {
[self.a foo]; // calling protected method foo from outside A and its subclasses
}
@end
@interface Parent
- (void)anAbstractMethod __attribute__((annotate("oclint:enforce[subclass must implement]")));
@end
@interface Child : Parent
@end
@implementation Child
/*
// Child, as a subclass of Parent, must implement anAbstractMethod
- (void)anAbstractMethod {}
*/
@end
for (int i = 0; i < 10; i++)
{
if (foo(i))
{
continue;
}
break; // this break is confusing
}
typedef enum {
value1 = 0,
value2 = 1
} eValues;
void aMethod(eValues a)
{
switch(a)
{
case value1:
break;
case value2:
break;
default: // this break is obsolete because all
break; // values of variable a are already covered.
}
}
void example(int a)
{
switch (a) {
case 1:
break;
default: // the default case should be last
break;
case 2:
break;
}
}
class Base { // class Base should have a virtual destructor ~Base()
public: virtual void f();
};
class Child : public Base {
public: ~Child(); // destructor ~Child() should be virtual
};
if (a != 0) // if (a == 0)
{ // {
i = 1; // i = 0;
} // }
else // else
{ // {
i = 0; // i = 1;
} // }
return !i ? -1 : 1; // return i ? 1 : -1;
@interface Foo : NSObject
{
int _bar;
}
@property (assign, nonatomic) int bar;
@end
@implementation Foo
@synthesize bar = _bar;
- (void)doSomething {
_bar = 3; // access _bar outside its getter, setter or init
}
@end
if (a < 0){a = 0; // reassign parameter a to 0}
)int *doSomething(int a) {
if (!foo(a) && bar(a) && doOtherThing(a)) {
// ... some really long code ....
}
return 0;
}
// is preferred as
int *doSomething(int a) {
if (foo(a)) {
return 0;
}
if (!bar(a)) {
return 0;
}
if (!doOtherThing(a)) {
return 0;
}
// ... some long code ....
}
try
{
int* m= new int[1000];
}
catch(...) // empty catch statement, this swallows an exception
{
}
do
{ // empty do-while statement
} while(1);
if (1)
{
return a + 1;
}
else // empty else statement, can be safely removed
{
}
Foo *foo;
@try
{
[foo bar];
}
@catch(NSException *e)
{
NSLog(@"Exception occurred: %@", [e description]);
}
@finally // empty finally statement, probably forget to clean up?
{
}
for (;;) // empty for statement
{
}
for (id it in array) // empty for-each statement
{
}
if (a == 1) // empty if statement
{
}
switch (i) // empty switch statement
{
}
void aMethod()
{
NSNumber *fortyTwo = [NSNumber numberWithInt:(43 - 1)];
// NSNumber *fortyTwo = @(43 - 1);
NSString *env = [NSString stringWithUTF8String:getenv("PATH")];
// NSString *env = @(getenv("PATH"));
}
void aMethod()
{
NSArray *a = [NSArray arrayWithObjects:@1, @2, @3, nil];
// NSArray *a = @[ @1, @2, @3 ];
NSDictionary *d = [NSDictionary dictionaryWithObjects:@[@2,@4] forKeys:@[@1,@3]];
// NSDictionary *d = @{ @1 : @2, @3 : @4 };
}
void aMethod()
{
NSNumber *fortyTwo = [NSNumber numberWithInt:42];
// NSNumber *fortyTwo = @42;
NSNumber *yesBool = [NSNumber numberWithBool:YES];
// NSNumber *yesBool = @YES;
}
void aMethod(NSArray *a, NSDictionary *d)
{
id item = [a objectAtIndex:0];
// id item = a[0];
id item = [d objectForKey:@1];
// id item = d[@1];
}
void example(int a, int b, int c)
{
bool b1 = a > b ? true : false; // true/false: bool b1 = a > b;
bool b2 = a > b ? false : true; // false/true: bool b2 = !(a > b);
int i1 = a > b ? 1 : 1; // same constant: int i1 = 1;
float f1 = a > b ? 1.0 : 1.00; // equally constant: float f1 = 1.0;
int i2 = a > b ? c : c; // same variable: int i2 = c;
}
bool example(int a, int b)
{
if (a == b) // this if statement is redundant
{
return true;
}
else
{
return false;
} // the entire method can be simplified to return a == b;
}
int example(int a)
{
int b = a * 2;
return b; // variable b is returned immediately after its declaration,
} // can be simplified to return a * 2;
+ (void)compare:(A *)obj1 withOther:(A *)obj2
{
if (obj1 && [obj1 isEqualTo:obj2]) // if ([obj1 isEqualTo:obj2]) is okay
{
}
}
bool example(int a)
{
if (a == 1) // if (a == 1)
{ // {
cout << "a is 1."; // cout << "a is 1.";
return true; // return true;
} // }
else //
{ //
cout << "a is not 1." // cout << "a is not 1."
} //
}
void m(char* c) {
if (c != nullptr) { // and be simplified to delete c;
delete c;
}
int example(int a)
{
int y = (a + 1); // int y = a + 1;
if ((y > 0)) // if (y > 0)
{
return a;
}
return (0); // return 0;
}
class c
{
int a, b;
int c;
// ...
int l;
int m, n;
// ...
int x, y, z;
void m() {}
};
class c
{
int a();
int b();
int c();
// ...
int l();
int m();
int n();
// ...
int x();
int y();
int z();
int aa();
int ab();
int ac();
int ad();
int ae();
};
void example(int a, int b, int c, int d, int e, int f,
int g, int h, int i, int j, int k, int l)
{
}
注:这些规则你可以在http://docs.oclint.org/en/stable/rules/index.html?highlight=rules找到
之后的博客会更新如何自定义检查规则,敬请期待。