anope- supernets anope source code & configuration |
git clone git://git.acid.vegas/anope.git |
Log | Files | Refs | Archive | README |
CODING (8270B)
1 Originally pulled from: https://wiki.inspircd.org/Coding_Guidelines 2 3 --- 4 5 InspIRCd Coding Guidelines 6 7 The following are a set of guidelines for writing patches to InspIRCd, or for 8 creating modules for distribution with the official package. These guidelines 9 were written a time after InspIRCd development started, and so not all code 10 yet follows these. This will be rectified with time. 11 12 13 1. Comments 14 15 * Multi Line 16 Multiple line comments should follow the C-style comment, for example: 17 /* 18 * This is a multiple line comment, huzzah.. 19 */ 20 21 * Single Line 22 Single line comments should also be in the C style, for example: 23 /* This is a boring one-line comment */ 24 25 * Doxygen commenting 26 If you wish your comment to show in doxygen, the comment should be directly 27 above the item you are documenting (a class, function, enum, etc) and the 28 first line should be "/**". For example: 29 /** This is a doxygen multiline comment. 30 * Description of thingymebob here. 31 */ 32 33 The first line after the "**" is used as the short description of the item 34 (up to the full stop) and everything afterwards as the detailed description. 35 36 37 2. Indentation 38 39 Tabs. Tabs. ONLY TABS. Use a single tab for each level of indentation, 40 for example: 41 int main() 42 { 43 <tab>if (condition) 44 <tab>{ 45 <tab><tab>code 46 <tab>} 47 } 48 49 50 3. Separation 51 52 Always put a space in between a keyword like if/while and the condition, 53 for example: 54 if (foo == bar) 55 NOT 56 if(foo == bar) 57 58 59 4. Braces 60 61 Always put braces opening and closing blocks on separate lines, see the 62 indentation example. For example, place braces like this: 63 if (apples == "green") 64 { 65 cout << "Apples are green" << endl; 66 } 67 68 and not: 69 if (apples == "green") { 70 cout << "Apples are green" << endl; 71 } 72 73 The one exception to this is if you are declaring a class method which is 74 only one line long, in that case the following is acceptable in most cases: 75 class foo : public bar 76 { 77 foo() { } 78 getrandomfoo() { return rand(); } 79 }; 80 81 82 5. Templates 83 84 Where possible, use templates rather than #defines. Avoid use of RTTI. 85 86 87 6. Structs 88 89 Structs should be declared in the following fashion: 90 struct BodyPartBasket 91 { 92 int arms; 93 int legs; 94 int scrotalsacs; 95 }; 96 and not like this: 97 typedef struct 98 { 99 int arms; 100 int legs; 101 int scrotalsacs; 102 } BodyPartBasket; 103 104 The second way is not required in C++ to be able to do this: 105 BodyPartBasket mybasket; 106 107 Plus, placing the name at the bottom of the declaration makes readability 108 more difficult (as you have to scroll down to the bottom of the struct to 109 find its name). (where possible, call them classes rather than structs.) 110 111 112 7. Variable naming 113 114 Class and struct names should be in camel case with a leading capital letter, 115 for example "MyBagOfBones" and not "my_bag_of_bones" or "mybagofbones". 116 Variable names can be in either camel case with a leading capital letter or 117 alternatively all lower case, so long as the same naming convention is 118 adhered to throughout the class. No classes or variables should be named in 119 capitals unless this makes sense for the name (for example "class DNS"). 120 Constants and enum values should always be completely in CAPITALS and 121 underscores may be used, for example: 122 enum DecayState 123 { 124 DECAYED_MOULDY = 0, 125 DECAYED_SMELLY = 1, 126 DECAYED_MAGGOTS = 2 127 }; 128 All value names in an enum should be started with the same text which should 129 be related in some way to the enum's use. For example "DNS_CNAME, DNS_A, 130 DNS_AAAA". 131 132 133 8. Use of references 134 135 Wherever possible, when dealing with any complex class, pass a const reference 136 rather than a copy of the class. For example: 137 MyThingy::MyThingy(const std::string &thingyvalue) 138 { 139 } 140 Of course, if you intended to change the string you can just omit the 'const'. 141 142 143 9. Use of char pointers 144 145 Whenever you use char pointers (char*, char**) try to use const equivalents. 146 This is much safer and avoids ugly and dangerous casts. For example: 147 MyThingy::Thingify(const char* const* wotsits) 148 { 149 } 150 If it is possible without performance loss, consider avoiding char pointers 151 altogether and using std::string instead. 152 153 154 10. Use of STL 155 156 For more information on use of STL in InspIRCd, please see the separate 157 STL FAQ. 158 159 160 11. Making copies of data 161 162 Never ever make a copy of a piece of data unless it is absolutely necessary. 163 For example, don't use strlcpy() to make a copy of the const char* string 164 returned by std::string::c_str(), if the change can be done to the std::string 165 itself. The same goes for unnecessary variable assignments, especially those 166 which assign large classes. 167 168 169 12. namespace std 170 171 Avoid the following: 172 using namespace std; 173 It might take a bit more typing, but things work better if you don't set 174 (then later assume) the namespace -- specify it explicitly when you want to 175 use it. 176 177 178 13. Linefeeds 179 180 Unix linefeeds only please. We do not like to see our screens covered in ^M. 181 182 183 14. Portability 184 185 Always make sure your code is portable to all supported operating systems, 186 remember of course that as of 1.1.8 this includes windows. Don't write code 187 that only works on windows, or only works on Linux. Test your code on all 188 platforms or ask for help from other developers who have the platforms you 189 want to test on. 190 191 * new() and delete(), malloc() and free() 192 Apart from the fact that using malloc() and free() is bad practice in C++ 193 code, you must never use malloc() or free() in InspIRCd, within its modules 194 or within the core. This is because if you use malloc() or free() in windows, 195 the memory is claimed from the program's local heap. 196 In windows, each shared object (module, dll) has its own heap, which is 197 protected from other dlls and executables. To get around this issue and 198 allow more posix-like memory access from other dlls in the program (other 199 modules), InspIRCd overrides the operators new and delete to ensure that 200 memory allocated by them comes from the windows global heap. If you use 201 malloc() and free() for this, the ircd will segfault when another module 202 tries to access the memory you have allocated! 203 204 * strdup() 205 As with malloc(), above, strdup() should be avoided. Where strdup() is 206 absolutely necessary, use strnewdup() which is our strdup() implementation 207 that calls operator new instead of using malloc(). 208 char arrays allocated by strnewdup() should be deleted with operator delete[]. 209 210 * CoreExport and DllImport 211 Prefix all types you want to import or export to other modules with CoreExport 212 and DllImport macros. These do nothing in POSIX operating systems, however 213 in windows these are expanded to the instructions __declspec(dllimport) and 214 __declspec(dllexport) respectively depending on where they are used and how. 215 216 217 15. External Dependencies 218 219 If a module is compiled as standard, or the code is part of the core, you must 220 not use any dependencies that are not available as standard on all supported 221 operating systems beyond libstdc++, libc, and whatever else is currently 222 required to build the core. Modules which use nonstandard dependencies belong 223 in the modules/extra directory. 224 225 226 16. Profiling and Performance 227 228 It is one thing to assume that code performs bad, it is another thing to prove 229 that it actually is. A lot of experienced programmers talk about 'premature 230 optimisation', and here is what it means: if you have a piece of code called 231 once on startup that takes 10 seconds instead of one second to run, and a 232 piece of code that takes 0.05 seconds to run when it should take 0.01, and 233 it is called once per second, the second piece of code is the priority. 234 235 In other words, make sure that what you think is slow, and a performance 236 problem in Insp actually is. 237 To do this, use the callgrind tool from Valgrind (valgrind --tool=cachegrind 238 bin/inspircd -nofork -debug), and kcachegrind (or similar) to view the output 239 files.