Difference between revisions of "Coding Conventions"

Jump to navigation Jump to search
→‎Struct packing: -- code highlighting
(→‎Language features: Mention C++98 explicitly)
(→‎Struct packing: -- code highlighting)
(One intermediate revision by the same user not shown)
Line 29: Line 29:
Do *not* assume that structs are stored in a certain way in memory -- the layout of a struct in memory can vary a lot between platforms, and on most modern systems it will almost never be "packed". If you absolutely must use packed structs, do not just use some #pragma or __attribute__ (as that is not portable either). Instead, do the following:
Do *not* assume that structs are stored in a certain way in memory -- the layout of a struct in memory can vary a lot between platforms, and on most modern systems it will almost never be "packed". If you absolutely must use packed structs, do not just use some #pragma or __attribute__ (as that is not portable either). Instead, do the following:
* Before the struct(s) you need to be packed, insert
* Before the struct(s) you need to be packed, insert
<source lang="cpp">
   #include "common/pack-start.h" // START STRUCT PACKING
   #include "common/pack-start.h" // START STRUCT PACKING
</source>
* After the struct(s) you need to be packed, insert
* After the struct(s) you need to be packed, insert
<source lang="cpp">
   #include "common/pack-end.h" // END STRUCT PACKING
   #include "common/pack-end.h" // END STRUCT PACKING
</source>
* At the "end" of each struct you need to be packed, insert the following between the closing } and the ; after it:
* At the "end" of each struct you need to be packed, insert the following between the closing } and the ; after it:
<source lang="cpp">
   PACKED_STRUCT
   PACKED_STRUCT
 
</source>
You may want to look at some files which already do that, e.g. look at <code>engines/scumm/boxes.cpp</code>
You may want to look at some files which already do that, e.g. look at <code>engines/scumm/boxes.cpp</code>


Line 49: Line 54:


The second issue concerns problems causing engines to be non-reentrant. Consider a code snippet like this:
The second issue concerns problems causing engines to be non-reentrant. Consider a code snippet like this:
<syntax type="C++">
<source lang="cpp">
   bool foo(bool cond) {
   bool foo(bool cond) {
     static bool bar = false;
     static bool bar = false;
Line 56: Line 61:
     return bar;
     return bar;
   }
   }
</syntax>
</source>
Suppose this function is part of engine quux. When a new game using this engine is started, foo(false) will initially always return false. After foo(true) has been called the first time, foo will always return true. Maybe foo(true) is called when the user/player solves a certain puzzle in the game, and maybe the foo() function is meant to test whether this puzzle has already been solved.
Suppose this function is part of engine quux. When a new game using this engine is started, foo(false) will initially always return false. After foo(true) has been called the first time, foo will always return true. Maybe foo(true) is called when the user/player solves a certain puzzle in the game, and maybe the foo() function is meant to test whether this puzzle has already been solved.
Now imagine the player uses the "return to launcher" feature; once back in the launcher, they restart the game, again using the quux engine.
Now imagine the player uses the "return to launcher" feature; once back in the launcher, they restart the game, again using the quux engine.
Line 62: Line 67:


This is another important reason why global variables keeping state are dangerous. At the very least, you ''must'' re-init any global variables whenever your engine starts. Relying on one-time initialization assignments to global variables, as in
This is another important reason why global variables keeping state are dangerous. At the very least, you ''must'' re-init any global variables whenever your engine starts. Relying on one-time initialization assignments to global variables, as in
<syntax type="C++">
<source lang="cpp">
   static int myGlobal = 0;
   static int myGlobal = 0;
</syntax>
</source>
is ''not'' sufficient.
is ''not'' sufficient.


Line 70: Line 75:


In addition, global variables are strongly discouraged; if they are to be used, then they ''must'' be accompanied by a comment that explains why this static variable is necessary, and why it cannot be replaced by something else, like typically a member variable of a suitable class / object. The comment should also indicate where the variable is (re)set when the engine launches. If no such comment is present, a generic comment of the following form shall be added to the variable declaration:
In addition, global variables are strongly discouraged; if they are to be used, then they ''must'' be accompanied by a comment that explains why this static variable is necessary, and why it cannot be replaced by something else, like typically a member variable of a suitable class / object. The comment should also indicate where the variable is (re)set when the engine launches. If no such comment is present, a generic comment of the following form shall be added to the variable declaration:
<syntax type="C++">
<source lang="cpp">
   // FIXME: non-const global var
   // FIXME: non-const global var
</syntax>
</source>


As a minor exception, if an existing engine uses many globals (due to not (yet) being objectified), it is permissible to use a single comment to document multiple globals at once.
As a minor exception, if an existing engine uses many globals (due to not (yet) being objectified), it is permissible to use a single comment to document multiple globals at once.

Navigation menu