[TUT] Code Styling & Good Programming Habits
Before we begin, this article is for anyone of any skill level. If you're just starting out, this will help you avoid nasty habits that you may pick up now or later. If you're an intermediate level scripter, you're probably relatively capable in terms of producing something that people can use, but may have trouble helping others understand your code properly.
This is an addendum to this post, which I don't feel is complete enough and needed some additions. This article will teach you what I believe are the best coding styles. I don't even follow all of these because I started out with some bad habits and they are hard to break. All of these are tried and tested but may still be up for debate. Some of these are indisputable while others are highly subjective. For those which I think are subjective, I'll always leave multiple options and state that they are not conventions. So without further ado, here we go. The Opening Comment Block The best place to start is, logically, the beginning of the plugin, where you place comments explaining what the plugin is and does. I often ignore this section for small plugins or ones which I'm not going to release. This is, however, good form for a plugin which you are planning on releasing on its own. A typical comment block may look like this: PHP Code:
Your opening comment block can look however you want it to, but the most important thing is that it gets the information out. If you find your style is impeding this, it's probably a good idea to revise it. Macros and the Preprocessor This section includes stuff such as your header inclusions (a.k.a. "#include") and compiler definitions (a.k.a. "#define"). There's not a whole lot you can do here in terms of messing up convention, but one of the important things to remember is that all macros should be capitalized from beginning to end. For example, PHP Code:
PHP Code:
PHP Code:
Another stylistic consideration is that your header inclusions should be as minimalistic as possible. For example, if you don't use any FakeMeta functions, don't include the fakemeta.inc file as it is useless clutter. One other important thing you should know about preprocessor styling is that conditions should generally be left untabbed. This makes it very clear where blocks of code will operate and where they won't. For example: PHP Code:
The final thing you should know is that, as in my previous example, it's a good idea to leave a comment at each #else, #elseif and #endif command denoting what exactly it's checking. Indentation, Tabbing and Spacing Tabbing should always be done whenever you open a code block (which will be discussed more in detail later). A standard tab is either done using the "Tab" key or using 4 spaces. Less commonly, people use 1, 3 or 8 spaces for their tabs, but this is very rare and generally frowned upon. Almost everyone uses the "Tab" key because then other people can set their tab-size higher or lower in their text editors. There are also many styles of spacing, but I believe the best (despite my not using it personally) is to add a space whenever you put a parameter in brackets, after a comma, immediately after a condition/loop keyword and before/after any operators which take two parameters on the left and right. For example: PHP Code:
PHP Code:
This is by no means standard and is highly up for debate, but to me this makes the most logical sense and is what I would use if I had the option of immediately wiping my habits and picking a new set of them. I would, however, advise you to always add spaces between operators with two parameters and after commas. You may also consider adding two carriage returns as opposed to one between functions as it may make them easier to read. This is by no means a convention but I recommend it personally. Case This is important mostly for variables and functions. I'm putting this here because I'm going to be implying it in my next section, which covers global variables. This section is largely up for debate, but I believe the strongest and most legible way of doing it is what is commonly referred to as "camel case". There's a slight variant of camel case called "mixed case" which I believe is slightly better. Here's how it goes: For functions, you always capitalize the first letter of every word. For example: PHP Code:
PHP Code:
PHP Code:
Mixed/camel case more or less necessitates totally avoiding using underscores. For example, this looks really weird: PHP Code:
Also, as noted earlier, macros should be full upper-case. Global Variables and Type Prefixing Lots of confusion can come from not knowing that something is global. As such, all global variables should be prefixed with some sort of tag identifying them as such. For example: PHP Code:
PHP Code:
You should add a carriage return at the end of every global variable as it makes it easier to search out any variables you need. For example: PHP Code:
PHP Code:
PHP Code:
In terms of a technical analysis, HN for anything other than global variables and pointers doesn't make any sense. Pawn is typeless and therefore incapable of actual data types. Booleans are actually just a meaningless tag and floats are cells which are converted by the virtual machine (AMXX's C++ side) whenever they are needed. There are many situations where HN will make variable casting/detagging confusing. Code Blocks A code block is anything that is separated by curly braces. While this may be an imprecise definition since in many code blocks the curly braces can simply be left out, I'm going to be addressing this style anyway. The first thing I'd like to address is spacing. There are two common ways of spacing your code blocks, one of which I believe is vastly superior. The first is by adding a return before the condition opening a block, the second is not doing this. For example: PHP Code:
PHP Code:
Another very important concept in code blocks is whether or not to drop them entirely. Under some very special circumstances, you can actually ignore the brackets denoting a code block. There are two cases which make this acceptable:
1. PHP Code:
PHP Code:
This method of dropping brackets is highly subjective. There are many arguments both for and against each. Dropping brackets allows you to type less code, but including them makes it less ambiguous. It can be argued, however, that ambiguity is resolved by tabbing even if there's no brackets. This style is up to you and either way is perfectly acceptable. Commenting Commenting is one of the most important things you can do for your code. Even if you break all of these habits, you can still get away with it if your commenting is good enough. Large blocks of text outside of functions should be commented using the "/* ... */" operators, as in the first section which covered the opening code block. All other sections should be commented using the "//" operator. The reason for this is that Pawn does not support nested comments, i.e.: PHP Code:
If you need nested comments, a little-known way of doing this is by using the preprocessor #if along with the condition 0, i.e.: PHP Code:
When commenting, you should keep your comment on each line below 80 characters. This is to prevent the compiler from complaining and is also for people who do not have widescreen displays. The "line below 80 characters" rule applies for any line of code, not just comments. Some people also space their comment out with one extra space (for two spaces in total) after the first line. I believe this makes it more readable, but this is highly subjective. Your comments should always be as descriptive as possible. You should inform the reader of what you're doing, why and what the result will be. For example, this is a bad comment as it serves no constructive use: PHP Code:
PHP Code:
PHP Code:
Whitespace Whitespace is a very important concept in coding. Although it has technically been covered previously in the "Tabbing and Spacing" section, there is still the issue of when to use carriage returns. If used correctly, whitespace allows people to understand your code more effectively. There are many different styles of using whitespace, but I believe the best is to simply add an extra carriage return whenever you break away from a part of a function which has similar results. For example: PHP Code:
Variable and Function Naming As a rule of thumb, variable and function names should be as descriptive as possible. For example, this is a bad variable name: PHP Code:
PHP Code:
For functions, it is generally advised to follow the same rule except in the situation where you're creating a hook. Often, you should tag your hook callbacks with what type of callback they are. For example, an event might be tagged with "Event" or a forward with "Forward". This can be seen as follows: PHP Code:
PHP Code:
Extras This section contains things that didn't really fit into other sections. For starters, you should always use constants whenever they're provided. For example, use: PHP Code:
PHP Code:
Semicolons are useful if you plan on moving to C/C++/PHP or any related language, but are often misused (for example, most people don't know do while loops have to be ended with one) or are passively used. Being a C and other related languages programmer myself, I have no trouble switching between using and not using semicolons. Since it's a convenience Pawn affords, I take it and don't use them. You can force semicolons using the following: PHP Code:
PHP Code:
PHP Code:
In conclusion, even if you ignore most of these tips, I hope you follow at least some of them as you will find them invaluable as you move along in the process of learning how to code. Ideally, you should follow all of these, but many people find them difficult to use or not as clean as their alternative. As I think of more stuff to add, I may do this, but for the most part I believe this tutorial is complete. As always, if you have questions or comments, feel free to post or PM me. EDIT: I bit the bullet and decided to actually learn to use the style that I advocate here. I have posted a plugin that uses this here: http://forums.alliedmods.net/showthread.php?t=102839 |
Re: [TUT] Code Styling
Awesome work Hawk, but I'd like to share some personal beliefs and preferences:
I believe Pawn is the kind of language that needs HN the most. Not having explicit typing makes it impossible to people not familiar with the code to find out what a cell actually holds without reading through a chunk of it. That information should be present in the variable itself, not in how it's used. And as there are no pointers in Pawn, I prefer to use the word 'handle', but both are perfectly fine as far as you're consistent in your code. Also, I prefer to include type prefixes even in global vars: g_iUseCount, g_szWebsite, etc 2 prefixes that you might see in some code (including mine), not included in your post: h for handles: Handle:hSQLConnection v for vectors: Float:vPlayerOrigin[3] And finally, I use the 'doxygen style' to document functions possibly used a lot, or that may interest other authors in case there is a sub-plugin system or anything like that: PHP Code:
|
Re: [TUT] Code Styling
great tut hawk :wink:
|
Re: [TUT] Code Styling
Nice.
I myself prefer HN. Didn't knew that this was possible: Code:
About function names... I'm still not decided, but currently I write only the first letter (or letters, if function's type title is made from 2 words, like forward - fw). Like eDeathMsg() for event and cSay for command. Also sPrint() for stock. BTW is the g_Test pointer (although danielkza said there are no pointers in Pawn) or a normal integer? Code:
|
Re: [TUT] Code Styling
Quote:
|
Re: [TUT] Code Styling
I strongly agree with the "Tabbing and Spacing" part
Its soo annoying when u get a wall of text in the source Good tut +k |
Re: [TUT] Code Styling
Quote:
BTW I prefer 8 spaces if there's no way to display big tab-space (like in this forum). In Notepad 8 spaces have equal lenght as 1 tab-space. |
Re: [TUT] Code Styling
Quote:
|
Re: [TUT] Code Styling
Good post! Lots of controversial stuff. ;)
I thought that I read somewhere that it is more efficient for the assembly to use one "new" statement for all of your vars (where applicable), as opposed to a different "new" for each one. Is there any truth to that? |
Re: [TUT] Code Styling
Quote:
|
All times are GMT -4. The time now is 08:12. |
Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.