规则集 | 分类 | 规则项 | 描述 | 严重等级 | 测试用例 | 修复后测试用例 | 正确测试用例解释 |
GJB_8114(国家军用标准C/C++语言可靠性编程规范) | GJB_A_01_01_声明定义(建议) | GJB_A_01_01_01 建议使用typedef对基本变量类型重新定义 | 建议 | unsigned int ua; // not-1 int ia; // not-2 unsigned short usa; // not-3 unsigned char uc; // not-4 float f; // not-5 double d; // not-6 | typedef unsigned int UINT_32; typedef int SINT_32; typedef unsigned short UINT_16; typedef unsigned char UCHAR; typedef float FLOAT_32; typedef double FLOAT_64; UINT_32 ua; // ok-1 SINT_32 ia; // ok-2 UINT_16 usa; // ok-3 UCHAR uc; // ok-4 FLOAT_32 f; // ok-5 FLOAT_64 d; // ok-6 | 使用typedef对基本变量类型重新定义 | |
GJB_A_01_01_02 谨慎由于宏中括号不匹配造成使用上的误解 | 建议 | #define IFO(x) if(0 == (x)) { // not-1 int main(void) { int test = 0; IFO(test) test = test + 1; } return 0; } | #define IFO(x) if(0==(x)) // ok-1 int main(void) { int test = 0; IFO(test) { test = test + 1; } return 0; } | 去掉函数宏中的括号 | |||
GJB_A_01_01_03 宏定义中谨慎使用##或# | 建议 | #include <stdio.h> typedef unsigned int UINT_32; typedef unsigned char UCHAR; UCHAR string[50]; #define cat(x) (&string[##(x)]) // not-1 void static_125( UCHAR string[50], UINT_32 n) { UCHAR *token1; token1=cat(n); } | #include <stdio.h> typedef unsigned int UINT_32; typedef unsigned char UCHAR; UCHAR string[50]; #define cat(x) (&string[(x)]) // ok-1 void static_125( UCHAR string[50], UINT_32 n) { UCHAR *token1; token1=cat(n); } | 去掉第(6)行宏定义中的## | |||
GJB_A_01_01_04 建议函数内部变量在函数体开始处统一定义 | 建议 | int fun_bad(int a) { int b; char* c; if(b==0){} //.. char arr[2]; // not-1 //... return 0; } | int fun_good(int a) { int b; char* c; char arr[2]; // ok-1 if(b==0){} //.. //... return 0; } | 将函数内部变量[arr]挪到函数体开始处统一定义 | |||
GJB_A_01_01_05 建议结构体嵌套定义不超过3层 | 建议 | struct D { int id; }; struct C { struct D sd; }; struct B { struct C sc; }; struct A // not-1 { struct B sb; }; | struct C { int id; }; struct B { struct C sc; }; struct A // ok-1 { struct B sb; }; | 修改结构体定义,确保嵌套不超过3层。 | |||
GJB_A_01_01_06 建议用宏或const定义常量 | 建议 | int fun_bad(double pi1) { if(1){ double pi2 = 3.1415926; // not-1 } double pi4 = pi1+3.1415926; return (0); } | #define PI 3.1415926 int fun_good1(double pi1) { if(1){ double pi2 = PI; // ok-1 } double pi4 = pi1+PI; return (0); } const double pi = 3.1415926; int fun_good2(double pi1) { if(1){ double pi2 = pi; // ok-2 } double pi4 = pi1+pi; return (0); } | 在第(1)行用宏定义常量[3.1415926],或者在第(12)行用const定义常量[3.1415926]。 | |||
GJB_A_01_02_版面书写(建议) | GJB_A_01_02_01 一个文件中的语句总行不超过2000行 | 建议 | ERROR, The maximum length of cell contents (text) is 32,767 characters | #include <stdio.h> #include <stdlib.h> #include <string.h> #define UCHR unsigned char #define SHA32 unsigned int #define SHA64 unsigned long long #define W32 SHA32 /* useful abbreviations */ #define SHA_H_SIZE sizeof(SHA64) * 8 #define SHA384_BLOCK_BITS 1024 #define SHA512_BLOCK_BITS SHA384_BLOCK_BITS #define SHA_MAX_BLOCK_BITS SHA512_BLOCK_BITS #define SHA512_DIGEST_BITS 512 #define SHA_MAX_DIGEST_BITS SHA512_DIGEST_BITS #define SHA_MAX_HEX_LEN (SHA_MAX_DIGEST_BITS / 4) #define SHA_MAX_BASE64_LEN (1 + (SHA_MAX_DIGEST_BITS / 6)) #define SHA32_CONST(c) c ## U #define C32 SHA32_CONST #define SHA32_SCHED(W, b) { int t; SHA32 *q = W; \ for (t = 0; t < 16; t++, b += 4) *q++ = \ (SHA32) b[0] << 24 | (SHA32) b[1] << 16 | \ (SHA32) b[2] << 8 | (SHA32) b[3]; } #define SHA32_SHR(x, n) ((x) >> (n)) #define SHA32_SHL(x, n) ((x) << (n)) #define SR32 SHA32_SHR #define SL32 SHA32_SHL #define Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) #define Pa(x, y, z) ((x) ^ (y) ^ (z)) #define Ma(x, y, z) (((x) & (y)) | ((z) & ((x) | (y)))) #define ROTR(x, n) (SR32(x, n) | SL32(x, 32-(n))) #define SIGMA0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) #define SIGMA1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) #define sigma0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SR32(x, 3)) #define sigma1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SR32(x, 10)) #define M2(a, b, c, d, e, f, g, h, w) \ T1 = h + SIGMA1(e) + Ch(e, f, g) + (*kp++) + w; \ h = T1 + SIGMA0(a) + Ma(a, b, c); d += T1; #define W21(s) W[(s+ 0) & 0xf] #define W22(s) W[(s+14) & 0xf] #define W23(s) W[(s+ 9) & 0xf] #define W24(s) W[(s+ 1) & 0xf] #define A2(s) (W21(s) += sigma1(W22(s)) + W23(s) + sigma0(W24(s))) #define M21(w) M2(a, b, c, d, e, f, g, h, w) #define M22(w) M2(h, a, b, c, d, e, f, g, w) #define M23(w) M2(g, h, a, b, c, d, e, f, w) #define M24(w) M2(f, g, h, a, b, c, d, e, w) #define M25(w) M2(e, f, g, h, a, b, c, d, w) #define M26(w) M2(d, e, f, g, h, a, b, c, w) #define M27(w) M2(c, d, e, f, g, h, a, b, w) #define M28(w) M2(b, c, d, e, f, g, h, a, w) static W32 K256[64] = /* SHA-224/256 constants */ { C32(0x428a2f98), C32(0x71374491), C32(0xb5c0fbcf), C32(0xe9b5dba5), C32(0x3956c25b), C32(0x59f111f1), C32(0x923f82a4), C32(0xab1c5ed5), C32(0xd807aa98), C32(0x12835b01), C32(0x243185be), C32(0x550c7dc3), C32(0x72be5d74), C32(0x80deb1fe), C32(0x9bdc06a7), C32(0xc19bf174), C32(0xe49b69c1), C32(0xefbe4786), C32(0x0fc19dc6), C32(0x240ca1cc), C32(0x2de92c6f), C32(0x4a7484aa), C32(0x5cb0a9dc), C32(0x76f988da), C32(0x983e5152), C32(0xa831c66d), C32(0xb00327c8), C32(0xbf597fc7), C32(0xc6e00bf3), C32(0xd5a79147), C32(0x06ca6351), C32(0x14292967), C32(0x27b70a85), C32(0x2e1b2138), C32(0x4d2c6dfc), C32(0x53380d13), C32(0x650a7354), C32(0x766a0abb), C32(0x81c2c92e), C32(0x92722c85), C32(0xa2bfe8a1), C32(0xa81a664b), C32(0xc24b8b70), C32(0xc76c51a3), C32(0xd192e819), C32(0xd6990624), C32(0xf40e3585), C32(0x106aa070), C32(0x19a4c116), C32(0x1e376c08), C32(0x2748774c), C32(0x34b0bcb5), C32(0x391c0cb3), C32(0x4ed8aa4a), C32(0x5b9cca4f), C32(0x682e6ff3), C32(0x748f82ee), C32(0x78a5636f), C32(0x84c87814), C32(0x8cc70208), C32(0x90befffa), C32(0xa4506ceb), C32(0xbef9a3f7), C32(0xc67178f2) }; typedef struct SHA { int alg; void (*sha)(struct SHA *, unsigned char *); unsigned char H[SHA_H_SIZE]; unsigned char block[SHA_MAX_BLOCK_BITS/8]; unsigned int blockcnt; unsigned int blocksize; SHA32 lenhh, lenhl, lenlh, lenll; unsigned char digest[SHA_MAX_DIGEST_BITS/8]; int digestlen; char hex[SHA_MAX_HEX_LEN+1]; char base64[SHA_MAX_BASE64_LEN+1]; } SHA; static void sha256(SHA *s, UCHR *block) /* SHA-224/256 transform */ { W32 a, b, c, d, e, f, g, h, T1; W32 W[16]; // S_15_01 数组w[16]未初始化使用误报 W32 *kp = K256; W32 *wp = W; W32 *H = (W32 *) s->H; SHA32_SCHED(W, block); // 数组w[16]赋值位置 /* * Use same technique as in sha1() * * To improve performance, unroll the loop and consolidate assignments * by changing the roles of variables "a" through "h" at each step. * Note that the variable "T2" is no longer needed. */ a = H[0]; b = H[1]; c = H[2]; d = H[3]; e = H[4]; f = H[5]; g = H[6]; h = H[7]; M21( *wp++); M22( *wp++); M23( *wp++); M24( *wp++); M25( *wp++); M26( *wp++); M27( *wp++); M28( *wp++); M21( *wp++); M22( *wp++); M23( *wp++); M24( *wp++); M25( *wp++); M26( *wp++); M27( *wp++); M28( *wp ); M21(A2( 0)); M22(A2( 1)); M23(A2( 2)); M24(A2( 3)); M25(A2( 4)); M26(A2( 5)); M27(A2( 6)); M28(A2( 7)); M21(A2( 8)); M22(A2( 9)); M23(A2(10)); M24(A2(11)); M25(A2(12)); M26(A2(13)); M27(A2(14)); M28(A2(15)); M21(A2( 0)); M22(A2( 1)); M23(A2( 2)); M24(A2( 3)); M25(A2( 4)); M26(A2( 5)); M27(A2( 6)); M28(A2( 7)); M21(A2( 8)); M22(A2( 9)); M23(A2(10)); M24(A2(11)); M25(A2(12)); M26(A2(13)); M27(A2(14)); M28(A2(15)); M21(A2( 0)); M22(A2( 1)); M23(A2( 2)); M24(A2( 3)); M25(A2( 4)); M26(A2( 5)); M27(A2( 6)); M28(A2( 7)); M21(A2( 8)); M22(A2( 9)); M23(A2(10)); M24(A2(11)); M25(A2(12)); M26(A2(13)); M27(A2(14)); M28(A2(15)); H[0] += a; H[1] += b; H[2] += c; H[3] += d; H[4] += e; H[5] += f; H[6] += g; H[7] += h; } | |||
GJB_A_01_02_02 一个函数中的语句总行不超过200行 | 建议 | #include <stdio.h> #include <stdlib.h> #include <string.h> typedef char Char; typedef unsigned char Bool; typedef unsigned char UChar; typedef int Int32; typedef unsigned int UInt32; typedef short Int16; typedef unsigned short UInt16; void BZ2_bz__AssertH__fail ( int errcode ) { // fprintf(stderr, // "\n\nbzip2/libbzip2: internal error number %d.\n" // "This is a bug in bzip2/libbzip2, %s.\n" // "Please report it to me at: jseward@bzip.org. If this happened\n" // "when you were using some program which uses libbzip2 as a\n" // "component, you should also report this bug to the author(s)\n" // "of that program. Please make an effort to report this bug;\n" // "timely and accurate bug reports eventually lead to higher\n" // "quality software. Thanks. Julian Seward, 10 December 2007.\n\n", // errcode, // BZ2_bzlibVersion() // ); if (errcode == 1007) { // fprintf(stderr, // "\n*** A special note about internal error number 1007 ***\n" // "\n" // "Experience suggests that a common cause of i.e. 1007\n" // "is unreliable memory or other hardware. The 1007 assertion\n" // "just happens to cross-check the results of huge numbers of\n" // "memory reads/writes, and so acts (unintendedly) as a stress\n" // "test of your memory system.\n" // "\n" // "I suggest the following: try compressing the file again,\n" // "possibly monitoring progress in detail with the -vv flag.\n" // "\n" // "* If the error cannot be reproduced, and/or happens at different\n" // " points in compression, you may have a flaky memory system.\n" // " Try a memory-test program. I have used Memtest86\n" // " (www.memtest86.com). At the time of writing it is free (GPLd).\n" // " Memtest86 tests memory much more thorougly than your BIOSs\n" // " power-on test, and may find failures that the BIOS doesn't.\n" // "\n" // "* If the error can be repeatably reproduced, this is a bug in\n" // " bzip2, and I would very much like to hear about it. Please\n" // " let me know, and, ideally, save a copy of the file causing the\n" // " problem -- without which I will be unable to investigate it.\n" // "\n" // ); } exit(3); } #define BZ_RAND_DECLS \ Int32 rNToGo; \ Int32 rTPos \ #define __inline__ /* */ #define True ((Bool)1) #define False ((Bool)0) #define BZ_MAX_ALPHA_SIZE 258 #define BZ_N_ITERS 4 #define BZ_N_GROUPS 6 #define BZ_G_SIZE 50 #define BZ_LESSER_ICOST 0 #define BZ_GREATER_ICOST 15 #define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE)) #define VPrintf0(zf) \ fprintf(stderr,zf) #define VPrintf1(zf,za1) \ fprintf(stderr,zf,za1) #define VPrintf2(zf,za1,za2) \ fprintf(stderr,zf,za1,za2) #define VPrintf3(zf,za1,za2,za3) \ fprintf(stderr,zf,za1,za2,za3) #define VPrintf4(zf,za1,za2,za3,za4) \ fprintf(stderr,zf,za1,za2,za3,za4) #define VPrintf5(zf,za1,za2,za3,za4,za5) \ fprintf(stderr,zf,za1,za2,za3,za4,za5) #define AssertH(cond,errcode) \ { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); } #define UPHEAP(z) \ { \ Int32 zz, tmp; \ zz = z; tmp = heap[zz]; \ while (weight[tmp] < weight[heap[zz >> 1]]) { \ heap[zz] = heap[zz >> 1]; \ zz >>= 1; \ } \ heap[zz] = tmp; \ } #define DOWNHEAP(z) \ { \ Int32 zz, yy, tmp; \ zz = z; tmp = heap[zz]; \ while (True) { \ yy = zz << 1; \ if (yy > nHeap) break; \ if (yy < nHeap && \ weight[heap[yy+1]] < weight[heap[yy]]) \ yy++; \ if (weight[tmp] < weight[heap[yy]]) break; \ heap[zz] = heap[yy]; \ zz = yy; \ } \ heap[zz] = tmp; \ } #define WEIGHTOF(zz0) ((zz0) & 0xffffff00) #define DEPTHOF(zz1) ((zz1) & 0x000000ff) #define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3)) #define ADDWEIGHTS(zw1,zw2) \ (WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \ (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2))) #define bsNEEDW(nz) \ { \ while (s->bsLive >= 8) { \ s->zbits[s->numZ] \ = (UChar)(s->bsBuff >> 24); \ s->numZ++; \ s->bsBuff <<= 8; \ s->bsLive -= 8; \ } \ } typedef struct { char *next_in; unsigned int avail_in; unsigned int total_in_lo32; unsigned int total_in_hi32; char *next_out; unsigned int avail_out; unsigned int total_out_lo32; unsigned int total_out_hi32; void *state; void *(*bzalloc)(void *,int,int); void (*bzfree)(void *,void *); void *opaque; }bz_stream; typedef struct { /* pointer back to the struct bz_stream */ bz_stream* strm; /* mode this stream is in, and whether inputting */ /* or outputting data */ Int32 mode; Int32 state; /* remembers avail_in when flush/finish requested */ UInt32 avail_in_expect; /* for doing the block sorting */ UInt32* arr1; UInt32* arr2; UInt32* ftab; Int32 origPtr; /* aliases for arr1 and arr2 */ UInt32* ptr; UChar* block; UInt16* mtfv; UChar* zbits; /* for deciding when to use the fallback sorting algorithm */ Int32 workFactor; /* run-length-encoding of the input */ UInt32 state_in_ch; Int32 state_in_len; BZ_RAND_DECLS; /* input and output limits and current posns */ Int32 nblock; Int32 nblockMAX; Int32 numZ; Int32 state_out_pos; /* map of bytes used in block */ Int32 nInUse; Bool inUse[256]; UChar unseqToSeq[256]; /* the buffer for bit stream creation */ UInt32 bsBuff; Int32 bsLive; /* block and combined CRCs */ UInt32 blockCRC; UInt32 combinedCRC; /* misc administratium */ Int32 verbosity; Int32 blockNo; Int32 blockSize100k; /* stuff for coding the MTF values */ Int32 nMTF; Int32 mtfFreq [BZ_MAX_ALPHA_SIZE]; UChar selector [BZ_MAX_SELECTORS]; UChar selectorMtf[BZ_MAX_SELECTORS]; UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; /* second dimension: only 3 needed; 4 makes index calculations faster */ UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4]; }EState; void BZ2_hbMakeCodeLengths ( UChar *len, Int32 *freq, Int32 alphaSize, Int32 maxLen ) { /*-- Nodes and heap entries run from 1. Entry 0 for both the heap and nodes is a sentinel. --*/ Int32 nNodes, nHeap, n1, n2, i, j, k; Bool tooLong; Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ]; Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ]; Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ]; for (i = 0; i < alphaSize; i++) weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8; while (True) { nNodes = alphaSize; nHeap = 0; heap[0] = 0; weight[0] = 0; parent[0] = -2; for (i = 1; i <= alphaSize; i++) { parent[i] = -1; nHeap++; heap[nHeap] = i; UPHEAP(nHeap); } AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 ); while (nHeap > 1) { n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1); n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1); nNodes++; parent[n1] = parent[n2] = nNodes; weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]); parent[nNodes] = -1; nHeap++; heap[nHeap] = nNodes; UPHEAP(nHeap); } AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 ); tooLong = False; for (i = 1; i <= alphaSize; i++) { j = 0; k = i; while (parent[k] >= 0) { k = parent[k]; j++; } len[i-1] = j; if (j > maxLen) tooLong = True; } if (! tooLong) break; /* 17 Oct 04: keep-going condition for the following loop used to be 'i < alphaSize', which missed the last element, theoretically leading to the possibility of the compressor looping. However, this count-scaling step is only needed if one of the generated Huffman code words is longer than maxLen, which up to and including version 1.0.2 was 20 bits, which is extremely unlikely. In version 1.0.3 maxLen was changed to 17 bits, which has minimal effect on compression ratio, but does mean this scaling step is used from time to time, enough to verify that it works. This means that bzip2-1.0.3 and later will only produce Huffman codes with a maximum length of 17 bits. However, in order to preserve backwards compatibility with bitstreams produced by versions pre-1.0.3, the decompressor must still handle lengths of up to 20. */ for (i = 1; i <= alphaSize; i++) { j = weight[i] >> 8; j = 1 + (j / 2); weight[i] = j << 8; } } } void BZ2_hbAssignCodes ( Int32 *code, UChar *length, Int32 minLen, Int32 maxLen, Int32 alphaSize ) { Int32 n, vec, i; vec = 0; for (n = minLen; n <= maxLen; n++) { for (i = 0; i < alphaSize; i++) if (length[i] == n) { code[i] = vec; vec++; }; vec <<= 1; } } static __inline__ void bsW ( EState* s, Int32 n, UInt32 v ) { bsNEEDW ( n ); s->bsBuff |= (v << (32 - s->bsLive - n)); s->bsLive += n; } static void sendMTFValues ( EState* s ) { Int32 v, t, i, j, gs, ge, totc, bt, bc, iter; Int32 nSelectors, alphaSize, minLen, maxLen, selCtr; // S_15_01 变量nSelectors误报 Int32 nGroups, nBytes; /*-- UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; is a global since the decoder also needs it. Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; are also globals only used in this proc. Made global to keep stack frame size small. --*/ UInt16 cost[BZ_N_GROUPS]; Int32 fave[BZ_N_GROUPS]; UInt16* mtfv = s->mtfv; if (s->verbosity >= 3) VPrintf3( " %d in block, %d after MTF & 1-2 coding, " "%d+2 syms in use\n", s->nblock, s->nMTF, s->nInUse ); alphaSize = s->nInUse+2; for (t = 0; t < BZ_N_GROUPS; t++) for (v = 0; v < alphaSize; v++) s->len[t][v] = BZ_GREATER_ICOST; /*--- Decide how many coding tables to use ---*/ AssertH ( s->nMTF > 0, 3001 ); if (s->nMTF < 200) nGroups = 2; else if (s->nMTF < 600) nGroups = 3; else if (s->nMTF < 1200) nGroups = 4; else if (s->nMTF < 2400) nGroups = 5; else nGroups = 6; /*--- Generate an initial set of coding tables ---*/ { Int32 nPart, remF, tFreq, aFreq; nPart = nGroups; remF = s->nMTF; gs = 0; while (nPart > 0) { tFreq = remF / nPart; ge = gs-1; aFreq = 0; while (aFreq < tFreq && ge < alphaSize-1) { ge++; aFreq += s->mtfFreq[ge]; } if (ge > gs && nPart != nGroups && nPart != 1 && ((nGroups-nPart) % 2 == 1)) { aFreq -= s->mtfFreq[ge]; ge--; } if (s->verbosity >= 3) VPrintf5( " initial group %d, [%d .. %d], " "has %d syms (%4.1f%%)\n", nPart, gs, ge, aFreq, (100.0 * (float)aFreq) / (float)(s->nMTF) ); for (v = 0; v < alphaSize; v++) if (v >= gs && v <= ge) s->len[nPart-1][v] = BZ_LESSER_ICOST; else s->len[nPart-1][v] = BZ_GREATER_ICOST; nPart--; gs = ge+1; remF -= aFreq; } } /*--- Iterate up to BZ_N_ITERS times to improve the tables. ---*/ for (iter = 0; iter < BZ_N_ITERS; iter++) { for (t = 0; t < nGroups; t++) fave[t] = 0; for (t = 0; t < nGroups; t++) for (v = 0; v < alphaSize; v++) s->rfreq[t][v] = 0; /*--- Set up an auxiliary length table which is used to fast-track the common case (nGroups == 6). ---*/ if (nGroups == 6) { for (v = 0; v < alphaSize; v++) { s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v]; s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v]; s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v]; } } nSelectors = 0; // 变量nSelectors赋值 totc = 0; gs = 0; while (True) { /*--- Set group start & end marks. --*/ if (gs >= s->nMTF) break; ge = gs + BZ_G_SIZE - 1; if (ge >= s->nMTF) ge = s->nMTF-1; /*-- Calculate the cost of this group as coded by each of the coding tables. --*/ for (t = 0; t < nGroups; t++) cost[t] = 0; if (nGroups == 6 && 50 == ge-gs+1) { /*--- fast track the common case ---*/ register UInt32 cost01, cost23, cost45; register UInt16 icv; cost01 = cost23 = cost45 = 0; # define BZ_ITER(nn) \ icv = mtfv[gs+(nn)]; \ cost01 += s->len_pack[icv][0]; \ cost23 += s->len_pack[icv][1]; \ cost45 += s->len_pack[icv][2]; \ BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4); BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9); BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14); BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19); BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24); BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29); BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34); BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39); BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44); BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49); # undef BZ_ITER cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16; cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16; cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16; } else { /*--- slow version which correctly handles all situations ---*/ for (i = gs; i <= ge; i++) { UInt16 icv = mtfv[i]; for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv]; } } /*-- Find the coding table which is best for this group, and record its identity in the selector table. --*/ bc = 999999999; bt = -1; for (t = 0; t < nGroups; t++) if (cost[t] < bc) { bc = cost[t]; bt = t; }; totc += bc; fave[bt]++; s->selector[nSelectors] = bt; nSelectors++; /*-- Increment the symbol frequencies for the selected table. --*/ if (nGroups == 6 && 50 == ge-gs+1) { /*--- fast track the common case ---*/ # define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++ BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4); BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9); BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14); BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19); BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24); BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29); BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34); BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39); BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44); BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49); # undef BZ_ITUR } else { /*--- slow version which correctly handles all situations ---*/ for (i = gs; i <= ge; i++) s->rfreq[bt][ mtfv[i] ]++; } gs = ge+1; } if (s->verbosity >= 3) { VPrintf2 ( " pass %d: size is %d, grp uses are ", iter+1, totc/8 ); for (t = 0; t < nGroups; t++) VPrintf1 ( "%d ", fave[t] ); VPrintf0 ( "\n" ); } /*-- Recompute the tables based on the accumulated frequencies. --*/ /* maxLen was changed from 20 to 17 in bzip2-1.0.3. See comment in huffman.c for details. */ for (t = 0; t < nGroups; t++) BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]), alphaSize, 17 /*20*/ ); } AssertH( nGroups < 8, 3002 ); AssertH( nSelectors < 32768 && /* 此处误报nSelectors未初始化使用 */ nSelectors <= (2 + (900000 / BZ_G_SIZE)), 3003 ); /*--- Compute MTF values for the selectors. ---*/ { UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp; for (i = 0; i < nGroups; i++) pos[i] = i; for (i = 0; i < nSelectors; i++) { /* 此处误报nSelectors未初始化使用 */ ll_i = s->selector[i]; j = 0; tmp = pos[j]; while ( ll_i != tmp ) { j++; tmp2 = tmp; tmp = pos[j]; pos[j] = tmp2; }; pos[0] = tmp; s->selectorMtf[i] = j; } }; /*--- Assign actual codes for the tables. --*/ for (t = 0; t < nGroups; t++) { minLen = 32; maxLen = 0; for (i = 0; i < alphaSize; i++) { if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; if (s->len[t][i] < minLen) minLen = s->len[t][i]; } AssertH ( !(maxLen > 17 /*20*/ ), 3004 ); AssertH ( !(minLen < 1), 3005 ); BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]), minLen, maxLen, alphaSize ); } /*--- Transmit the mapping table. ---*/ { Bool inUse16[16]; for (i = 0; i < 16; i++) { inUse16[i] = False; for (j = 0; j < 16; j++) if (s->inUse[i * 16 + j]) inUse16[i] = True; } nBytes = s->numZ; for (i = 0; i < 16; i++) if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0); for (i = 0; i < 16; i++) if (inUse16[i]) for (j = 0; j < 16; j++) { if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0); } if (s->verbosity >= 3) VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes ); } /*--- Now the selectors. ---*/ nBytes = s->numZ; bsW ( s, 3, nGroups ); bsW ( s, 15, nSelectors ); /* 此处误报nSelectors未初始化使用 */ for (i = 0; i < nSelectors; i++) { for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1); bsW(s,1,0); } if (s->verbosity >= 3) VPrintf1( "selectors %d, ", s->numZ-nBytes ); /*--- Now the coding tables. ---*/ nBytes = s->numZ; for (t = 0; t < nGroups; t++) { Int32 curr = s->len[t][0]; bsW ( s, 5, curr ); for (i = 0; i < alphaSize; i++) { while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ }; while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ }; bsW ( s, 1, 0 ); } } if (s->verbosity >= 3) VPrintf1 ( "code lengths %d, ", s->numZ-nBytes ); /*--- And finally, the block data proper ---*/ nBytes = s->numZ; selCtr = 0; gs = 0; while (True) { if (gs >= s->nMTF) break; ge = gs + BZ_G_SIZE - 1; if (ge >= s->nMTF) ge = s->nMTF-1; AssertH ( s->selector[selCtr] < nGroups, 3006 ); if (nGroups == 6 && 50 == ge-gs+1) { /*--- fast track the common case ---*/ UInt16 mtfv_i; UChar* s_len_sel_selCtr = &(s->len[s->selector[selCtr]][0]); Int32* s_code_sel_selCtr = &(s->code[s->selector[selCtr]][0]); # define BZ_ITAH(nn) \ mtfv_i = mtfv[gs+(nn)]; \ bsW ( s, \ s_len_sel_selCtr[mtfv_i], \ s_code_sel_selCtr[mtfv_i] ) BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4); BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9); BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14); BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19); BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24); BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29); BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34); BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39); BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44); BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49); # undef BZ_ITAH } else { /*--- slow version which correctly handles all situations ---*/ for (i = gs; i <= ge; i++) { bsW ( s, s->len [s->selector[selCtr]] [mtfv[i]], s->code [s->selector[selCtr]] [mtfv[i]] ); } } gs = ge+1; selCtr++; } AssertH( selCtr == nSelectors, 3007 ); if (s->verbosity >= 3) VPrintf1( "codes %d\n", s->numZ-nBytes ); } | |||||
GJB_A_01_02_03 C语言程序建议使用标准C的注释符,谨慎使用//注释 | 建议 | // GJB_A_01_02_03.c, not-1 int func(void) // not-2 { // not-3 return 0; } | /* GJB_A_01_02_03.c, ok-1 */ int func(void) /* ok-2 */ { /* ok-3 */ return 0; } | 使用标准C的/*…*/类型的注释符替代//注释。 | |||
GJB_A_01_03_指针使用(建议) | GJB_A_01_03_01 谨慎使用函数指针 | 建议 | typedef struct struct_fn_t { void (* s_fn)(struct struct_fn_t * s_fn_ptr); } struct_fn; void sda_054 ( void ) { struct_fn s_fn_ptrs[10]; struct_fn * sda_054_p = &s_fn_ptrs[0]; /* ----- */ sda_054_p->s_fn (sda_054_p++); /* Not compliant */ /* ----- */ } | ||||
GJB_A_01_03_02 谨慎使用无类型指针 | 建议 | #include<stdio.h> void* pvoid1; //Not Compliant void fun(void* p1) //Not Compliant { /*…*/ } int main(void) { void* pvoid2; //Not Compliant /*…*/ return (0); } | #include<stdio.h> char* pvoid1; //Not Compliant void fun(char* p1) //Not Compliant { /*…*/ } int main(void) { char* pvoid2; //Not Compliant /*…*/ return (0); } | 修改第[2]、[3]、[9]行变量的类型为char*类型 | |||
GJB_A_01_03_03 谨慎对指针进行算术运算 | 建议 | void fun(void) { int w = 10; int *p; p=&w; int * x=p++; //Not compliant p+1; //Not compliant } | void good_fun(void) { int arr[5]; int *p; p=arr; int * x=p++; //compliant p+1; //compliant } | 第[5]行指针[p]指向数组arr,第[6]、[7]行的指针进行算术运算 | |||
GJB_A_01_04_分支控制(建议) | GJB_A_01_04_01 避免层次过多的分支嵌套,建议最多不超过7层。 | 建议 | void main(void) { int i,j; if(i!=0) { if(0<i<100) { if(10<i<90) { if(20<i<80) { if(30<i<70) { if(40<i<60) { if(45<i<50) { if(i==48) //not complaint {printf("iiiiiiii");} } } } } } } } } | void main(void) { int i,j; if(i!=0) { if(0<i<100) { if(10<i<90) { if(20<i<80) { if(30<i<70) { if(40<i<60) { printf("iiiiiiii"); } } } } } } } | 减少if分支嵌套层次 | ||
GJB_A_01_05_跳转控制(建议) | GJB_A_01_05_01 谨慎使用goto语句。 | 建议 | #include<stdio.h> #define xx goto label1; //not compliant int main() { printf(" "); int i; for(i=1;i<10;i++) { xx; //not compliant } label1: i = 5; return 0; } | #include<stdio.h> int main() { printf(" "); int i; for(i=1;i<10;i++) { if(i == 5) break; } return 0; } | 去掉goto语句 | ||
GJB_A_01_06_运算处理(建议) | GJB_A_01_06_01 谨慎对有符号整型量进行位运算 | 建议 | int main(void) { signed int a = 5; unsigned int dd = 5; a << 5; //not compliant (int)dd <<3; //not compliant return 0; } | int main(void) { signed int a = 5; unsigned int dd = 5; (unsigned int)a << 5; dd <<3; return 0; } | 第[5]对无符号变量[(unsigned int)a]进行移位操作;第[6]行对无符号类型[dd]进行移位操作 | ||
GJB_A_01_06_02 谨慎做整型量除以整型变量的除法 | 建议 | int main(void) { int a = -2; int b = 4/a; //Not compliant return 0; } | int main(void) { int a = 2u; int b = 4u/a; //Not compliant return 0; } | 第[4]行做除法的两个整形量都是无符号类型的,不会存在负数的情况 | |||
GJB_A_01_06_03 动态申请的内存空间用完后及时释放 | 建议 | int fun() { int *a=(int *)malloc(sizeof(int));//not compliant } | |||||
GJB_A_01_06_04 避免使用strcpy函数,应使用strncpy函数替代 | 建议 | #include<string.h> void fun(void) { char *s="Hello World!"; char d[10]; strcpy(d,s); //Not Compliant } | #include<string.h> void fun(void) { char *s="Hello World!"; char d[10]; strncpy(d,s,9); } | 第[6]行使用strncpy函数,将[s]前[9]个字符赋值给[d] | |||
GJB_A_01_06_05 避免使用strcat函数,应使用strncat函数替代 | 建议 | #include<string.h> #include<stdio.h> int main() { char dest[7] = “hello ”; char *src = "world!"; char *temp = strcat(dest,src); // Not Compliant (dest分配的内存不足) } | #include<string.h> #include<stdio.h> int main() { char dest[7] = “hello ”; char *src = "world!"; char *temp = strncat(dest,src,1); // } | 第[8]行使用strncat函数,将[src]的前[1]个字符追加到[dest]缓冲区结尾处 | |||
GJB_A_01_06_06 谨慎使用逗号操作符 | 建议 | int main(void) { int a=8,b=9; int c = (a,b); //not compliant return 0; } | int main(void) { int a=8,b=9; int c =a; c = b; return 0; } | 将第[4]行的表达式拆开 | |||
GJB_A_01_07_函数调用(建议) | GJB_A_01_07_01 函数中避免使用过多的参数,建议不要超过10个 | 建议 | /*违背示例*/ int func(int a1,int a2,int a3,int a4,int a5, int a6,int a7,int a8,int a9,int a10,int a11)//not compliant { /*...*/ return 0; } | /*违背示例*/ int func(int a1,int a2,int a3,int a4,int a5, int a6,int a7,int a8)//compliant { /*...*/ return 0; } | 第[3]行的函数[func]的参数数量总共[8]个,未超出[10]个 | ||
GJB_A_01_07_02 函数中避免存在未被使用的调用参数 | 建议 | #include <stdio.h> void sort( int left, int* center, int *right) // not compliant { } int main() { return 0; } | #include <stdio.h> void sort(int left, int* center, int *right) { left = (right - center)/2; } int main() { return 0; } | 第[3]行的参数[left]、[right]、[center]在函数中均被使用 | |||
GJB_A_01_07_03 谨慎使用abort、exit函数 | 建议 | #include <stdio.h> #include <stdlib.h> int main(void) { char *s; abort(); //not compliant exit( EXIT_SUCCESS ); //not compliant } | #include <stdio.h> #include <stdlib.h> int main(void) { return 0; } | 去掉[abort]、[exit]函数,使用return语句退出函数 | |||
GJB_A_01_07_04 对系统函数的调用,建议调用后对其返回状态的有效性进行判别 | 建议 | #include<stdio.h> #include<stdlib.h> int main(void) { printf(“About to system command.com and run a DOS command\n”); char *p = (char* )malloc(10); //Not Compliant *p = 'a'; return (0); } | #include<stdio.h> #include<stdlib.h> int main(void) { printf(“About to system command.com and run a DOS command\n”); char *p = (char* )malloc(10); if(p == NULL) return 0; *p = 'a'; return (0); } | 第[6]行调用函数系统函数malloc,赋给指针p,第[7]行判断p是否为NULL | |||
GJB_A_01_07_05 函数中数组变量作为参数指针传递时,建议同时传递数组长度 | 建议 | void fun1(int p[]) //not compliant { int i; for(i=0;i<6;i++) { p[i]=p[i]+1; } } | void fun1(int p[], int i) //compliant { for(i=0;i<6;i++) { p[i]=p[i]+1; } } | 第[1]行数组[p]被当作指针参数,并传递数组的长度 | |||
GJB_A_01_08_语句使用(建议) | GJB_A_01_08_01 避免使用空语句 | 建议 | int main() { int i=0; if(i==0){}; //Not compliant } | int main() { int i=0; if(i==0){ //compliant i++; }; } | 修改第[4]行的if分支语句,空语句变成可执行的语句 | ||
GJB_A_01_08_02 避免无用的多余变量 | 建议 | int a; //not compliant int main() { int i; //not compliant return 0; } | int a; int main() { int i = a; i++; return i; } | 第[1]的变量[a]、[4]的变量[i]声明后有使用过 | |||
GJB_A_01_08_03 避免无用的多余函数 | 建议 | void used(){ /*...*/ } void unused(){ /*...*/ } int main(){ used(); return 0; //main函数结束,而函数unused从未被调用,所以之前函数unused的定义属于无效代码 } | |||||
GJB_A_01_08_04 推荐使用数字类型后缀 | 建议 | void fn(){ long int c = 10; //not compliant unsigned g = 8; //not compliant } | void fn(){ long int c = 10L; //not compliant unsigned g = 8u; //not compliant } | 第[2]行[long int]类型变量[c]、第[3]行[unsigned int]类型变量[g]赋值常量并加类型后缀。 | |||
GJB_A_01_09_循环控制(建议) | GJB_A_01_09_01 谨慎使用无限循环语句 | 建议 | int main() { for(;;) // not compliant { } while(1) // not compliant { } do { } while(2); // not compliant return 0; } | ||||
GJB_A_01_09_02 谨慎在循环中使用多个break语句 | 建议 | #include <math.h> #include <stdio.h> int main() { int i; for(i=1;i<10;i++) { if(i==1) { break; //not compliant continue; } else if(i==5) { break; //not compliant } printf("Number=%d\n",i); } } | #include <math.h> #include <stdio.h> int main() { int i; for(i=1;i<10;i++) { if(i==1) { continue; } else if(i==5) { break; } printf("Number=%d\n",i); } } | 第[6]的for循环中使用了第[14]行1个break语句 | |||
GJB_A_01_09_03 谨慎在循环中使用多个continue语句 | 谨慎在循环中使用多个continue语句 | 建议 | for(i=1;i<10;i++) { if(i==1) { continue; //not compliant continue; //not compliant } else if(i==5) { goto label1;continue; } printf("Number=%d\n",i); } | ||||
GJB_A_01_10_类型转换(建议) | GJB_A_01_10_01 浮点型数转换成整型数应考虑是否需要四舍五入 | 建议 | int fun(int ia) { float a = 2.1; int b = (int)(a); //not complaint return 0; } | ||||
GJB_A_01_10_02 谨慎将double型数转换成float型数 | 建议 | int main(void) { float a =(float)9.0; //not complaint double la =8.0; a = la; // not compliant } | |||||
GJB_A_01_10_03 谨慎将长整型数转换为短整型数 | 建议 | int main(void) { int a =9; long la =8; a = la; //Not compliant } | |||||
GJB_A_01_10_04 谨慎将指针变量赋予非指针变量或非指针变量赋予指针变量 | 建议 | int main(void) { unsigned int *ptr=NULL; unsigned int adr=0; unsigned int uid=0; ptr= adr; //not compliant return 0; } | int main(void) { unsigned int *ptr=NULL; unsigned int adr=0; unsigned int uid=0; ptr = (unsigned int *) uid; // compliant return 0; } | 第[6]行将[unsigned int*]类型的指针变量[adr]赋给[unsigned int*]类型的指针变量[ptr] | |||
GJB_A_01_11_初始化(建议) | GJB_A_01_11_01 建议变量在声明的同时进行初始化 | 建议 | int *p; //Not Compliant int fun(int a,char b) { int c; //Not Compliant float f; //Not Compliant f=0.0; char d='e'; b=c; /*...*/ return 0; } | int *p = 0; //Compliant int fun(int a,char b) { int c = 1; //Compliant float f = 1.0f; //Compliant f=0.0; char d='e'; b=c; /*...*/ return 0; } | 第[1]、[4]]、[5]的变量声明的同时进行初始化 | ||
GJB_A_01_11_02 建议所有全局变量在统一设计的初始化模块中进行初始化 | 建议 | /*声明全局变量*/ int a; float b; char* arr[3]; unsigned int var=0; //Not Compliant /*统一初始化所有全局变量*/ void globalVars(void) { a=1; b=1.0; char* arr[3]={'a','b','c'}; } | /*声明全局变量*/ int a; float b; char* arr[3]; unsigned int var; /*统一初始化所有全局变量*/ void globalVars(void) { a=1; b=1.0; char* arr[3]={'a','b','c'}; var = 0; } | 将第[5]的全局变量[var]在统一设计的初始化模块中进行初始化 | |||
GJB_A_01_12_表达式(建议) | GJB_A_01_12_01 与常数进行是否相等的判别,建议常数在左,变量在右 | 建议 | #include<stdlib.h> int main(void) { int i = 0; if(i == 0) //Not Compliant (建议常数在左) { /*…*/ } else { /*…*/ } int j = (i==0 ? 1:0); //Not Compliant return (0) } | #include<stdlib.h> int main(void) { int i = 0; if(0 == i) //Not Compliant (建议常数在左) { /*…*/ } else { /*…*/ } int j = (0 == i ? 1:0); //Not Compliant return (0) } | 第[6]、[14]行的变量[i]与常数[0]进行是否相等的比较,0在左,变量在右 | ||
GJB_A_01_13_变量使用(建议) | GJB_A_01_13_01 推荐使用带类型前缀的变量命名 | 建议 | #include<stdlib.h> int main(void) { int launchButton; //Not Compliant unsigned int flag; //Not Compliant /*...*/ return (0); } | #include<stdlib.h> int main(void) { int iLaunchButton; //OK unsigned int uiFlag; //OK /*...*/ return (0); } | 修改第[5]、[6]行声明的变量,加上类型前缀 | ||
GJB_A_01_13_02 谨慎使用寄存器变量 | 建议 | register int glb; //Not Compliant register int r_var; //Not Compliant void static_p(register int x) //Not Compliant { register int ri= 0; //Not Compliant for(register int i=0;i<4;i++) //Not Compliant { /*…*/ } } | int glb; //Compliant int r_var; //Compliant void static_p(int x) //Compliant { int ri= 0; //Compliant for(int i=0;i<4;i++) //Compliant { /*…*/ } } | 修改第[1]、[2]、[3]、[5]、[6]行的变量为普通变量 | |||
GJB_A_02_01_类与对象(建议) | GJB_A_02_01_01 谨慎使用派生类由虚拟基类派生 | 建议 | #include <iostream> using namespace std; class A { public: A(void); void SetA(int); private: int a; }; A::A(void):a(0) { } void A::SetA(int va) { a = va; } class B1:virtual public A //not complaint { public: B1(void); void SetB1(int); private: int b1; }; class B2:public virtual A //not complaint { public: B2(void); void setB2(int); private: int b2; }; class D:public B1, public B2 { public: D(void); private: int d; } int main(void) { return 0; } | #include <iostream> using namespace std; class A { public: A(void); void SetA(int); private: int a; }; A::A(void):a(0) { } void A::SetA(int va) { a = va; } class B1:public A //not complaint { public: B1(void); void SetB1(int); private: int b1; }; class B2:public A //not complaint { public: B2(void); void setB2(int); private: int b2; }; class D:public B1, public B2 { public: D(void); private: int d; } int main(void) { return 0; } | 第[18]的类[B1]、[26]行的类[B2]均由基类[A]派生 | ||
GJB_A_02_01_02 谨慎使用内联函数 | 建议 | #include <iostream> using namespace std; class A { public: inline void fun1(); //not complaint void fun2(void){} //not complaint }; void A::fun1(){} int main(void) { /*...*/ return 0; } | #include <iostream> using namespace std; class A { public: void fun1(); //not complaint void fun2(void){} //not complaint }; void A::fun1(){} int main(void) { /*...*/ return 0; } | 第[6]行成员函数[fun1]去掉inline关键字进行声明 | |||
GJB_A_02_05_类型转换(建议) | GJB_A_02_05_01 建议使用C++的类型转换操作符,避免使用C的类型转换形式 | 建议 | #include <iostream> using namespace std; class Base { public: Base(){}; virtual ~Base(){}; }; class Derived : public Base { public: Derived(){}; ~Derived(){}; }; int f(float f) //not complaint { return f; } int f(void) //OK { return 10; } int main() { Base *pB; Derived *pD2 = (Derived *) pB; // not complaint int a; char* c; float f; a = (int)c; //not complaint a = int (c); //not complaint a = reinterpret_cast<int>(c); //OK f = static_cast<float>(df); //OK } | ||||
GJB_A_02_07_函数定义与使用(建议) | GJB_A_02_07_01 类中函数的实现代码避免在类定义的内部定义 | 建议 | #include <iostream> using namespace std; class A { int i; void fun1(); //OK void fun2() //not complaint { } public: A(); ~A(); }; void A::fun1() { } int main() { /*...*/ return 0; } | #include <iostream> using namespace std; class A { int i; void fun1(); //OK void fun2(); // public: A(); ~A(); }; void A::fun1() { } void A::fun2() { } int main() { /*...*/ return 0; } | 第[7]的成员函数[fun2]定义在类[A]外 | ||
GJB_A_02_07_02 如果函数的指针和指针参数对应的对象不被修改,那么应该被声明为常量指针。 | 建议 | int fun1(int* ptr) // not complaint { return (*ptr) + 1; } int fun2(int & ptr) // not complaint { return ptr; } | int fun3(const int* ptr) // OK { return (*ptr) + 1; } int fun4(int* ptr) //OK(指针被修改,不加const) { ptr++; return (*ptr); } | 第[1]的指针参数变量[ptr]在函数体内并没有修改其值,所以被声明为指针常量;第[5]行的指针参数由于在函数体内发生了改变,所以不能申明为指针常量 | |||
GJB_A_02_08_异常处理(建议) | GJB_A_02_08_01 建议在所有指定捕获之后使用缺省捕获防范遗漏的异常 | 建议 | #include <iostream> using namespace std; class Document { public: Document (void):docid(0){} int get_docid(void); private: int docid; }; int Document::get_docid(void){} int main() { try { Document mydoc1; throw mydoc1; } catch (Document &d) { } //not complaint return 0; } | #include <iostream> using namespace std; class Document { public: Document (void):docid(0){} int get_docid(void); private: int docid; }; int Document::get_docid(void){} int main() { try { Document mydoc1; throw mydoc1; } catch (Document &d) { } catch(...) { } return 0; } | 第[21]行增加缺省的捕获 | ||
GJB_A_02_08_02 谨慎对指针类型进行抛出捕获 | 建议 | #include <iostream> using namespace std; int main() { int i; try { int a1 = 1; int *a2 = new int(2); if (i > 10) { throw &a1; } else { throw a2; //not complaint } } catch (int *b) { } return 0; } | #include <iostream> using namespace std; int main() { int i; try { int a1 = 1; if (i > 10) { throw &a1; } else { throw a1; } } catch (int *b) { } catch (int b) { } return 0; } | 第[14]行抛出了[int]类型的变量[a1] | |||
GJB_A_02_09_其他条款(建议) | GJB_A_02_09_01 建议模板参数列表中的类型参数使用typename关键字说明 | 建议 | #include <iostream> using namespace std; template <class T1, class T2> //not complaint T1 Max(T1 a, T2 b) { return a; } int main() { return 0; } | #include <iostream> using namespace std; template <typename T> //complaint T Max(T a, T b) { return a; } int main() { return 0; } | 修改第[3]行模板使用typename关键字 | ||
GJB_A_02_09_02 建议除常数指针外,const说明均在类型说明的最外层 | 建议 | int main(void) { int a; int const *p2 = &a; //not complaint--指针常数 int const b =1; //not complaint return 0; } | int good_fun() { int a; const int *p1 = &a; //ok--指针常数 int *const p3 = &a; //ok ---常数指针 const int c =1; //ok } | 修改第[4]const修饰符在类型[int]的左侧;第[5]行的const修饰符在类型[int]的左侧 | |||
GJB_A_02_09_03 逗号运算符, && 运算符和 || 运算符不得被重载 | 建议 | #include <iostream> using namespace std; class A { public: A( int i ) : _i( i ) {}; ~A( ){}; int value( ) { return _i; } private: int _i; }; bool operator&&( A& lhs, A& rhs ) //not complaint { return lhs.value( ) && rhs.value( ); } bool operator||( A& lhs, A& rhs ) //not complaint { return lhs.value( ) || rhs.value( ); } int operator,( A& lhs, A& rhs) //not complaint,重载易产生歧义 { return lhs.value( ); } int main() { A a(1); A b(0); bool f = a && b; } | |||||
GJB_A_02_09_04 建议不使用以.h为后缀的头文件 | 建议不使用以.h为后缀的头文件 | 建议 | #include <iostream.h> //not complaint #include "file1.h" //not complaint using namespace std; int main() { /*...*/ return 0; } | #include <iostream> //not complaint #include "file1.hh" //not complaint using namespace std; int main() { /*...*/ return 0; } | 第[1]使用不带后缀的库文件;第[2]行使用.hh为后缀的头文件 |
GJB 8114 建议规则
最新推荐文章于 2025-01-07 08:55:06 发布