1 I know, there are no bugfree programs, at least if they are large enough (like sendmail), they can't be bugfree.
2 sendmail again. The security problem won't be treated any more in this paper.
3 A software engineering biased quote: If it doesn't work, it can be fixed. If it can't be maintained, it's scrap. (Well, it may not work and can't be maintained either...)
4 Readable for a human, not for the compiler.
5 However, I put no recommendations where the choice is totally yours, e.g. chosing one of the much discussed indent styles.
6 Samples of good efficiency of other programming languages are the ability of Lisp environments to compile their functions and the possibility to post-compile Java virtual machine bytecode into native binary code.
7 K&R2 [BK/DR,1988] is based on the ANSI C draft X3J11/88-001 and was published before the ANSI standard ANS X3.159-1989. This standard was adopted as ISO/IEC 9899:1990 and is also known as ANSI/ISO 9899-1990. Note that ANSI and ISO require periodic reviews of their standards.
8 However, I find names as n or i quite speaking for local index variables. At least if the loops are kept small, as they should (for good modularity).
9 Underscores may not appear as such in a view that underlines identifier names (e.g. identifiers displayed as HTML hyperlinks). They appear to be blanks.
10 Considering the (historic) limitation of external identifier names to only six characters seems not feasible today. Not many good identifier names would result if you were to use only six characters or had to avoid the reuse of the same six starting characters.
11 The Java namespace model is based on (possibly large) hierarchical names, proposing internet domains as a base. Packages are named like com.sun.applet. This is a thought-out approach to get unique names.
12 One may ask if it was usual to provide only lean interfaces (only few functions) in C libraries partly because of the missing package support, and hence the possible name clashes with many names.
13 One of the reasons C is not specially suited for large software bases.
14 Note that I make a distinction between case-sensitive and case-preserving. The later doesn't allow you to save file names that only differ by case, although the case will be preserved.
15 If you intend to develop hybrid C/C++ code (not recommended).
16 Which will produce errors under C++. That's why casts are still seen with malloc() calls (in C/C++ hybrid code).
17 In C++, the name (but not the type) of the unused parameter can be left away. Nice solution.
18 Unlike the quantity, the quality of the comments can't easily be measured with metrics. However, it will be revealed by (human) code reviews.
19 Of course such things are more important if the software project is a large one.
20 Be sure however to have an operator precedence table at hand all the time.
21 Although abstract and generic programming is not so much supported as it is in C++.
22 Functions may check pointers for 0 and issue understandable diagnostics (instead of crash, e.g. printf() writing
23 The (object oriented) C++ class concept and inheritance decrease complexity even further.
24 To be avoided.
25 Note that if you want to link only the functions of your interface that are really used, and your linker can't throw unused functions out of an object file, you have to put each independent function in its own module and use an external header file.
26 Not so in C++. What was designed to allow function overloading will also do type checks in the link phase.
27 C does not allow type and macro redefinitions, even with the same definitions. Also, the include guards make it easier to allow circular header references (though not recommended).
28 To provide an interface that is open to C and C++, you may also want to declare C linkage in a similar way: #ifdef __cplusplus extern "C" { #endif ... #ifdef __cplusplus } #endif.
29 By the linker respectively the loader.
30 These styles obviously must be mixed when using indirect recursive functions that are implemented in the same module.
31 The editor needs to know about the defined macros then, obviously.
32 The C preprocessor usually can't do this, since it will also expand included header files and macros.
33 Compilers/optimizers tend to get confused if too many variables are present and give up optimization.
34 The C++ language offers additional encapsulation mechanisms with its class concept. By specifying members (data or functions) to be private (or protected), C++ can limit scope to certain (class) functions.
35 One may argue whether to insert generic blocks (not part of a function, loop or similar) to do additional variable scope narrowing. It can encapsulate variables in large flat legacy code, but it does not seem to be a good design decision.
36 However, using explicit access functions can be seen as a design flaw because modules should provide functionality, not plain data access.
37 If a monitor is used, the static data will be no problem. However, still no reference on the static data can be returned to multiple threads.
38 C++ introduced two less powerful casts to defuse the situation. (One to change a const specifier only and one to cast from one pointer type to another only.)
39 [BS,1997] sees casts (though in C++) (in most cases) as in indication of a design error.
40 C++ does not. This is one of the more obvious incompatibilities between C++ and C.
41 And C comes, unlike Lisp, not with a standard bignum (only resource-limited size) numeric type.
42 A process image (data and stack memory) that can be used for post mortem analysis of a program crash (on Unix).
43 Specially dangerous with (network) services and even more if they run with high operating system privileges.
44 C++ handles its memory allocation (operator new) with a bad_alloc exception and needs not be handled.
45 Lint may give you the warning "evaluation order undefined: p".
46 Unlike C++, C does not allow const int values to be used as array sizes. A macro definition must be used instead.
47 5/2 as upper approximation of 8*log10(2), with additional bytes for integer division truncation, sign and string termination. Don't forget to give this constant a meaningful name.
48 I'm not talking of implementing something like virtual memory support as part of operating system code here.
49 However since the memory layout is probably different on a 16 bit system (can't allocate large data chunks, must partitionate them), int/long portability will not be the only problem.
50 Of course also in operating system code; but in that context you can less say that the code should not assume of what size an int is.
51 This applies also to floating point numbers.
52 XDR (external data representation) e.g. used by RPC (remote procedure call) e.g. used by NFS (network file system).
53 The same happens with struct {long b; short a;}, to get the longs aligned in an array of such structs. The padding will in this case be at the end of the struct and not create a gap between the struct members.
54 These floating point handling routines may be quite large on operating systems that support processors that lack a floating point unit. Floating point logic may not be implemented on the operating system level on such systems (small embedded systems kernels being a sample).
55 Variable arguments are discouraged by C++. The C++ alternative is to provide different, overloaded functions. Calls to printf() are replaced by calls to ostream::operator<<().
56 C++ tends to absolutely not use the NULL macro.
57 Compilers must ignore at least some register keywords anyway if the programmer specifies too many.
58 Also, truly recursive functions (e.g. qsort) can be designed to descend the smaller branch(es) of the recursion tree first and take the last branch iteratively. This will lead to only small stack space requirements.
59 Users of functional programming languages may be pro-biased on this one.
60 However, two quotes (couldn't resist): Don't optimize early. When speed and space are an issue, style guides are thrown out the window (however, I do not totally agree with the last one).
61 I think modules should rather represent logical units than be limited in any physical form (e.g. in the number of lines of code).
62 These indent-style filters could even be triggered by revision control software upon check-out and check-in to let the programmer have its own style. However, this requires very consequent use of revision control tools, which may pose some unwanted overhead.
63 A special annoying style is an indentation with four blanks where every pair of four blanks is converted to one tab. This looks like half of the indent levels (2, 4, ...) are left out when viewed with a tabstop setting of four (instead of eight).
64 You may question the quality of such editors. They shouldn't be used for coding.
65 Note that a closing brace may serve as an anchor for debuggers. You may not be able to jump out of an unbraced loop in source debugging mode.
66 I do not recommend adding additional indent levels.
67 Not part of the C language, but tolerated by many C compilers.
68 C++ much more encourages mixed lines with code and comments because of its singleline comments construct.
69 In C++ a variable definition can appear anywhere a code statement can. This allows always immediate initialization.
70 Of course, there's always more.
Friday, January 9, 2009
Footnotes
Posted by abhilash at 9:06 AM
Subscribe to:
Post Comments (Atom)
0 Comments:
Post a Comment