#LyX 2.0.0svn created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass scrbook \use_default_options true \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \listings_params "basicstyle={\footnotesize}" \tracking_changes true \output_changes false \author "Kornel Benko" Kornel.Benko@berlin.de \end_header \begin_body \begin_layout Title LyX Development \begin_inset Newline newline \end_inset Rules and Recommendations \end_layout \begin_layout Chapter Rules for the code in LyX \begin_inset Foot status collapsed \begin_layout Plain Layout Updated from the C++STYLE distributed with the GNU C++ Standard. \end_layout \end_inset \end_layout \begin_layout Standard The aim of this file is to serve as a guide for the developers, to aid us to get clean and uniform code. This document is incomplete. We really like to have new developers joining the LyX Project. However, we have had problems in the past with developers leaving the project and their contributed code in a far from perfect state. Most of this happened before we really became aware of these issues, but still, we don't want it to happen again. So we have put together some guidelines and rules for the developers. \end_layout \begin_layout Section General \end_layout \begin_layout Standard These guidelines should save us a lot of work while cleaning up the code and help us to have quality code. LyX has been haunted by problems coming from unfinished projects by people who have left the team. Those problems will hopefully disappear if the code is easy to hand over to somebody else. In general, if you want to contribute to the main source, we expect at least that you: \end_layout \begin_layout Itemize the most important rule first: KISS (Keep It Simple Stupid), always use a simple implementation in favor of a more complicated one. This eases maintenance a lot. \end_layout \begin_layout Itemize write good C++ code: Readable, well commented and taking advantage of the OO model. Follow the formatting guidelines. See Formatting. \end_layout \begin_layout Itemize adapt the code to the structures already existing in LyX, or in the case that you have better ideas, discuss them on the developer's list before writing the code. \end_layout \begin_layout Itemize take advantage of the C++ standard library. Especially don't use custom containers when a standard container is usable; learn to use the algorithms and functors in the standard library. \end_layout \begin_layout Itemize be aware of exceptions and write exception safe code. See Exceptions. \end_layout \begin_layout Itemize document all variables, methods, functions, classes etc. We are using the source documentation program doxygen, a program that handles javadoc syntax, to document sources. You can download doxygen from: http://www.stack.nl/~dimitri/doxygen/ \end_layout \begin_layout Itemize we have certain code constructs that we try to follow. See Code Constructs. \end_layout \begin_layout Section Submitting Code \end_layout \begin_layout Standard It is implicitly understood that all patches contributed to The LyX Project is under the Gnu General Public License, version 2 or later. If you have a problem with that, don't contribute code. Also please don't just pop up out of the blue with a huge patch (or small) that changes something substantial in LyX. Always discuss your ideas with the developers on the developer's mailing list. When you create the patch, please use "diff -up" since we find that a lot easier to read than the other diff formats. Also please do not send patches that implements or fixes several different things; several patches is a much better option. We also require you to provide a commit message entry with every patch, this describes in detail what the patch is doing. \end_layout \begin_layout Section Code Constructs \end_layout \begin_layout Standard We have several guidelines on code constructs, some of these exist to make the code faster, others to make the code clearer. Yet others exist to allow us to take advantage of the strong type checking in C++. \end_layout \begin_layout Itemize Declaration of variables should wait as long as possible. The rule is: "Don't declare it until you need it." In C++ there are a lot of user defined types, and these can very often be expensive to initialize. This rule connects to the next rule too. \end_layout \begin_layout Itemize Declare the variable as const if you don't need to change it. This applies to POD types like int as well as classes. \end_layout \begin_layout Itemize Make the scope of a variable as small as possible. \end_layout \begin_layout Itemize Make good use of namespaces. Prefer anonymous namespaces to declaring "static" for file scope. \end_layout \begin_layout Itemize Prefer preincrement to postincrement whenever possible. \end_layout \begin_layout Itemize Preincrement has potential of being faster than postincrement. Just think about the obvious implementations of pre/post-increment. This rule applies to decrement too. \end_layout \begin_layout Itemize Use: \end_layout \begin_deeper \begin_layout Standard \begin_inset listings lstparams "basicstyle={\footnotesize},language={C++}" inline false status open \begin_layout Plain Layout ++T; \end_layout \begin_layout Plain Layout --U; \end_layout \end_inset \end_layout \begin_layout Standard Do not use: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout T++; // not used in LyX \end_layout \begin_layout Plain Layout U--;// not used in LyX \end_layout \end_inset \end_layout \end_deeper \begin_layout Itemize Try to minimize evaluation of the same code over and over. This is aimed especially at loops. \begin_inset Newline newline \end_inset Use: \end_layout \begin_deeper \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout Container::iterator end = large.end(); \end_layout \begin_layout Plain Layout for (Container::iterator it = large.begin(); it != end; ++it) { \end_layout \begin_layout Plain Layout ...; \end_layout \begin_layout Plain Layout } \end_layout \end_inset \end_layout \begin_layout Standard Do not use: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout for (Container::iterator it = large.begin(); it != large.end(); ++it) { \end_layout \begin_layout Plain Layout ...; \end_layout \begin_layout Plain Layout } \end_layout \end_inset \end_layout \end_deeper \begin_layout Itemize For functions and methods that return a non-POD type \begin_inset Foot status open \begin_layout Plain Layout Plain Ol' Data type \end_layout \end_inset T, return T const instead. This gives better type checking, and will give a compiler warning when temporaries are used wrongly. \end_layout \begin_deeper \begin_layout Standard Use: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout T const add(..); \end_layout \end_inset \end_layout \begin_layout Standard Do not use: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout T add(..); \end_layout \end_inset \end_layout \end_deeper \begin_layout Itemize Avoid using the default cases in switch statements unless you have too. Use the correct type for the switch expression and let the compiler ensure that all cases are exhausted. \end_layout \begin_layout Itemize \begin_inset listings inline false status open \begin_layout Plain Layout enum Foo { \end_layout \begin_layout Plain Layout FOO_BAR1, \end_layout \begin_layout Plain Layout FOO_BAR2 \end_layout \begin_layout Plain Layout }; \end_layout \begin_layout Plain Layout \end_layout \begin_layout Plain Layout Foo f = ...; \end_layout \begin_layout Plain Layout \end_layout \begin_layout Plain Layout switch (f) { \end_layout \begin_layout Plain Layout case FOO_BAR1: ...; \end_layout \begin_layout Plain Layout break; \end_layout \begin_layout Plain Layout case FOO_BAR2: ...; \end_layout \begin_layout Plain Layout break; \end_layout \begin_layout Plain Layout default: ...; \end_layout \begin_layout Plain Layout // not needed and would shadow a wrong use of Foo \end_layout \begin_layout Plain Layout break; \end_layout \begin_layout Plain Layout } \end_layout \end_inset \end_layout \begin_layout Section Exceptions \end_layout \begin_layout Standard Be aware of the presence of exceptions. One important thing to realize is that you often do not have to use throw, try or catch to be exception safe. Let's look at the different types of exceptions safety: (These are taken from Herb Sutter's book[ExC++] \end_layout \begin_layout Enumerate Basic guarantee: Even in the presence of exceptions thrown by T or other exceptions, Stack objects don't leak resources. Note that this also implies that the container will be destructible and usable even if an exception is thrown while performing some container operation. However, if an exception is thrown, the container will be in a consistent, but not necessarily predictable, state. Containers that support the basic guarantee can work safely in some settings. \end_layout \begin_layout Enumerate Strong guarantee: If an operation terminates because of an exception, program state will remain unchanged. This always implies commit-or-rollback semantics, including that no references or iterators into the container be invalidated if an operation fails. For example, if a Stack client calls Top and then attempts a Push that fails because of an exception, then the state of the Stack object must be unchanged and the reference returned from the prior call to Top must still be valid. For more information on these guarantees, see Dave Abrahams's documentation of the SGI exception-safe standard library adaption at: http://www.stlport.org/do c/exception_safety.html Probably the most interesting point here is that when you implement the basic guarantee, the strong guarantee often comes for free. For example, in our Stack implementation, almost everything we did was needed to satisfy just the basic guarantee -- and what's presented above very nearly satisfies the strong guarantee, with little o \change_inserted 0 1288157484 r \change_deleted 0 1288157483 f \change_unchanged no extra work. Not half bad, considering all the trouble we went to. In addition to these two guarantees, there is one more guarantee that certain functions must provide in order to make overall exception safety possible: \end_layout \begin_layout Enumerate No throw guarantee: The function will not emit an exception under any circumstan ces. Overall exception safety isn't possible unless certain functions are guaranteed not to throw. In particular, we've seen that this is true for destructors; later in this miniseries, we'll see that it's also needed in certain helper functions, such as Swap(). \end_layout \begin_layout Standard For all cases where we might be able to write exception safe functions without using try, throw or catch we should do so. In particular we should look over all destructors to ensure that they are as exception safe as possible. \end_layout \begin_layout Section Formatting \end_layout \begin_layout Itemize Only one declaration on each line. \end_layout \begin_deeper \begin_layout Standard Use: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout int a; \end_layout \begin_layout Plain Layout int b; \end_layout \end_inset \end_layout \begin_layout Standard Do not use: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout int a,b; // not used in LyX \end_layout \end_inset \end_layout \begin_layout Standard This is especially important when initialization is done at the same time: \end_layout \begin_layout Standard Use: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout string a = "Lars"; \end_layout \begin_layout Plain Layout string b = "Gullik"; \end_layout \end_inset \end_layout \begin_layout Standard Do not use: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout string a = "Lars", b = "Gullik"; // not used in LyX \end_layout \end_inset \end_layout \begin_layout Standard [Note that 'string a = "Lars"' is formally calling a copy constructor on a temporary constructed from a string literal and therefore has the potential of being more expensive then direct construction by 'string a("Lars")'. However the compiler is allowed to elide the copy (even if it had side effects), and modern compilers typically do so. Given these equal costs, LyX code favours the '=' idiom as it is in line with the traditional C-style initialization, _and_ cannot be mistaken as function declaration, _and_ reduces the level of nested parantheses in more initializations.] \end_layout \end_deeper \begin_layout Itemize Pointers and references: \end_layout \begin_deeper \begin_layout Standard Use: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout char * p = "flop"; \end_layout \begin_layout Plain Layout char & c = *p; \end_layout \end_inset \end_layout \begin_layout Standard Do not use: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout char *p = "flop"; // not used in LyX \end_layout \begin_layout Plain Layout char &c = *p; // not used in LyX \end_layout \end_inset \end_layout \begin_layout Standard Some time ago we had a huge discussion on this subject and after convincing argumentation from Asger this is what we decided. Also note that we will have: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout char const * p; \end_layout \end_inset \end_layout \begin_layout Standard and not \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout const char * p; // not used in LyX \end_layout \end_inset \end_layout \end_deeper \begin_layout Itemize Operator names and parentheses \end_layout \begin_deeper \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout operator==(type) \end_layout \end_inset \end_layout \begin_layout Standard and not \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout operator == (type) // not used in LyX \end_layout \end_inset \end_layout \begin_layout Standard The == is part of the function name, separating it makes the declaration look like an expression. \end_layout \end_deeper \begin_layout Itemize Function names and parentheses \end_layout \begin_deeper \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout void mangle() \end_layout \end_inset \end_layout \begin_layout Standard and not \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout void mangle () // not used in LyX \end_layout \end_inset \end_layout \end_deeper \begin_layout Itemize Enumerators \end_layout \begin_deeper \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout enum Foo { \end_layout \begin_layout Plain Layout FOO_ONE = 1, \end_layout \begin_layout Plain Layout FOO_TWO = 2, \end_layout \begin_layout Plain Layout FOO_THREE = 3 \end_layout \begin_layout Plain Layout }; \end_layout \end_inset \end_layout \begin_layout Standard and not \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout enum { one = 1, two = 2, three 3 }; // not used in LyX \end_layout \end_inset \end_layout \begin_layout Standard and not \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout enum { \end_layout \begin_layout Plain Layout One = 1, \end_layout \begin_layout Plain Layout Two = 2, \end_layout \begin_layout Plain Layout Three = 3 \end_layout \begin_layout Plain Layout }; \end_layout \end_inset \end_layout \end_deeper \begin_layout Itemize Null pointers \end_layout \begin_deeper \begin_layout Standard Using a plain 0 is always correct and least effort to type. So: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout void * p = 0; \end_layout \end_inset \end_layout \begin_layout Standard and not \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout void * p = NULL; // not used in LyX \end_layout \end_inset \end_layout \begin_layout Standard and not \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout void * p = ' \backslash 0'; // not used in LyX \end_layout \end_inset \end_layout \begin_layout Standard and not \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout void * p = 42 - 7 * 6; // not used in LyX \end_layout \end_inset \end_layout \begin_layout Standard Note: As an exception, imported third party code as well as code interfacing the "native" APIs (src/support/os_*) can use NULL. \end_layout \end_deeper \begin_layout Itemize Naming rules for classes \end_layout \begin_deeper \begin_layout Itemize Use descriptive but simple and short names. Do not abbreviate. \end_layout \begin_layout Itemize Class names are usually capitalized, and function names lowercased. \end_layout \begin_layout Itemize Enums are named like Classes, values are usually in lower-case. \end_layout \begin_layout Itemize Public API is camel-case ('void setAFlagToAValue(bool)') \end_layout \begin_layout Itemize Members variables are underscored ('enable_this_feature_flag_') with a final '_' \end_layout \begin_layout Itemize Private/protected functions are also camel-case \end_layout \begin_layout Itemize New types are capitalized, so this goes for typedefs, classes, structs and enums. \end_layout \end_deeper \begin_layout Itemize Formatting \end_layout \begin_deeper \begin_layout Itemize Adapt the formatting of your code to the one used in the other parts of LyX. In case there is different formatting for the same construct, use the one used more often. \end_layout \end_deeper \begin_layout Itemize Use existing structures \end_layout \begin_deeper \begin_layout Itemize \change_inserted 0 1288159254 \begin_inset CommandInset label LatexCommand label name "Use-string-wherever" \end_inset \change_unchanged Use string wherever possible. LyX will someday move to Unicode, and that will be easy if everybody uses string now. Unicode strings should prefer using docstring instead of UTF-8 encoded std::string. \end_layout \begin_layout Itemize Check out the filename and path tools in filetools.h \end_layout \begin_layout Itemize Check out the string tools in lstring.h. \end_layout \begin_layout Itemize Use the LyXErr class to report errors and messages using the lyxerr instantiatio n. [add description of other existing structures] \end_layout \end_deeper \begin_layout Itemize Declarations \end_layout \begin_deeper \begin_layout Itemize Use this order for the access sections of your class: public, protected, private. The public section is interesting for every user of the class. The private section is only of interest for the implementors of the class (you). [Obviously not true since this is for developers, and we do not want one developer only to be able to read and understand the implementation of class internals. Lgb] \end_layout \begin_layout Itemize Avoid declaring global objects in the declaration file of the class. If the same variable is used for all objects, use a static member. \end_layout \begin_layout Itemize Avoid global or static variables. \end_layout \end_deeper \begin_layout Itemize File headers \end_layout \begin_deeper \begin_layout Standard If you create a new file, the top of the file should look something like this : \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout /** \end_layout \begin_layout Plain Layout * \backslash file NewFile.cpp \end_layout \begin_layout Plain Layout * This file is part of LyX, the document processor. \end_layout \begin_layout Plain Layout * Licence details can be found in the file COPYING. \end_layout \begin_layout Plain Layout * \end_layout \begin_layout Plain Layout * \backslash author Kaiser Sose \end_layout \begin_layout Plain Layout * \end_layout \begin_layout Plain Layout * Full author contact details are available in file CREDITS \end_layout \begin_layout Plain Layout */ \end_layout \end_inset \end_layout \end_deeper \begin_layout Itemize Documentation \end_layout \begin_deeper \begin_layout Itemize The documentation is generated from the header files. \end_layout \begin_layout Itemize You document for the other developers, not for yourself. \end_layout \begin_layout Itemize You should document what the function does, not the implementation. \end_layout \begin_deeper \begin_layout Itemize in the .cpp files you document the implementation. \end_layout \end_deeper \begin_layout Itemize Single line description (///), multiple lines description (/** ... */) see the doxygen webpage referenced above \end_layout \end_deeper \begin_layout Section Naming rules for Lyx User Functions (LFUNs) \end_layout \begin_layout Standard Here is the set of rules to apply when a new command name is introduced: \end_layout \begin_layout Enumerate Use the object.event order. That is, use `word-forward' instead of`forward-word'. \end_layout \begin_layout Enumerate Don't introduce an alias for an already named object. Same for events. \end_layout \begin_layout Enumerate Forward movement or focus is called `forward' (not `right'). \end_layout \begin_layout Enumerate Backward movement or focus is called `backward' (not `left'). \end_layout \begin_layout Enumerate Upward movement of focus is called `up'. \end_layout \begin_layout Enumerate Downward movement is called `down'. \end_layout \begin_layout Enumerate The begin of an object is called `begin' (not `start'). \end_layout \begin_layout Enumerate The end of an object is called `end'. \end_layout \begin_layout Section How to create class interfaces \end_layout \begin_layout Standard (a.k.a How Non-Member Functions Improve Encapsulation) \end_layout \begin_layout Standard I recently read an article by Scott Meyers \change_deleted 0 1288158556 in \change_unchanged , where he makes a strong case on how non-member functions makes classes more encapsulated, not less. Just skipping to the core of this provides us with the following algorithm for deciding what kind of function to add to a class interface: \end_layout \begin_layout Itemize We need to add a function f to the class C's API. \end_layout \begin_deeper \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout if (f needs to be virtual) \end_layout \begin_layout Plain Layout make f a member function of C; \end_layout \begin_layout Plain Layout else if (f is operator>> or operator<<) { \end_layout \begin_layout Plain Layout make f a non-member function; \end_layout \begin_layout Plain Layout if (f needs access to non-public members of C) \end_layout \begin_layout Plain Layout make f a friend of C; \end_layout \begin_layout Plain Layout } else if (f needs type conversions on its left-most argument) { \end_layout \begin_layout Plain Layout make f a non-member function; \end_layout \begin_layout Plain Layout if (f needs access to non-public members of C) \end_layout \begin_layout Plain Layout make f a friend of C; \end_layout \begin_layout Plain Layout } else if (f can be implemented via C's public interface) \end_layout \begin_layout Plain Layout make f a non-member function; \end_layout \begin_layout Plain Layout else \end_layout \begin_layout Plain Layout make f a member function of C; \end_layout \end_inset \end_layout \end_deeper \begin_layout Chapter Recommendations \end_layout \begin_layout Standard These are some rules for effective C++ programming. These are taken from Scott Meyers \begin_inset CommandInset citation LatexCommand cite key "key-4" \end_inset , and are presented in their short form. These are not all the rules Meyers presents, only the most important of them. LyX does not yet follow these rules, but they should be the goal. \end_layout \begin_layout Itemize use const and inline instead of #define \end_layout \begin_layout Itemize use the same form in corresponding calls to new and delete, i.e. write delete[] obj; if new obj[n]; was used to create the object and write delete obj; if you wrote new obj; Notice strings should be std::string's instead of char *'s. \change_inserted 0 1288159280 (this contradicts to \begin_inset CommandInset ref LatexCommand ref reference "Use-string-wherever" \end_inset ) \change_unchanged \end_layout \begin_layout Itemize define a default constructor, copy constructor and an assignment operator for all classes with dynamically allocated memory that are not made noncopyable \end_layout \begin_layout Itemize do not define default constructor, copy constructor and an assignment operator if the compiler generated one would do the same \end_layout \begin_layout Itemize make destructors virtual in base classes and only there \end_layout \begin_layout Itemize assign to all data members in operator=() \end_layout \begin_layout Itemize strive for class interfaces that are complete and minimal \end_layout \begin_layout Itemize differentiate among member functions, global functions and friend functions \end_layout \begin_layout Itemize avoid data members in the public interface \end_layout \begin_layout Itemize use const whenever possible \end_layout \begin_layout Itemize pass and return objects by reference instead of by value \end_layout \begin_layout Itemize choose carefully between function overloading and parameter defaulting \end_layout \begin_layout Itemize never return a reference to a local object or a dereferenced pointer initialized by new within the function \end_layout \begin_layout Itemize use enums for integral constants \end_layout \begin_layout Itemize minimize compilation dependencies between files \end_layout \begin_layout Itemize pay attention to compiler warnings \end_layout \begin_layout Itemize differentiate between inheritance of interface and inheritance of implementation \end_layout \begin_layout Itemize differentiate between inheritance and templates \end_layout \begin_layout Itemize ensure that global objects are initialized before they are used \end_layout \begin_layout Itemize avoid conditions to 'if' and 'while' that span more than a line \end_layout \begin_layout Chapter \start_of_appendix Notes \end_layout \begin_layout Itemize And one of mine: (Lgb) \end_layout \begin_deeper \begin_layout Itemize when swi \change_inserted 0 1288159389 t \change_unchanged ching on enums, refrain from using "default:" if possible \end_layout \end_deeper \begin_layout Itemize And one of mine: (Andre') \end_layout \begin_deeper \begin_layout Itemize try to implement your class in a way that the automatically generated copy constructor and copy assignment work out-of-the box \end_layout \begin_layout Itemize I don't have problems with using boost in the implementation _if and only if_ it provides actual benefits over less intrusive alternatives. I do have a problem with needlessly sprinkling 'boost::' over interfaces, especially if it does not add any value. \end_layout \begin_deeper \begin_layout Standard Given that there seems to be an unconditional "typedef unsigned int quint32;" in qglobal.h I don't think there's any platform supported by current LyX that could not use 'unsigned int' (and an static assert in some implementation file for the unlikely case some ILP64 zombie raises its ugly head again. And if that happens, using would still be a better choice...) \end_layout \begin_layout Standard The idea is to create something that's not compilable as soon as the condition is violated. There are lots of possibilities to achieve this, some examples follow: \end_layout \begin_layout Standard In C++0x there's a "built-in": \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout static_assert(sizeof(int) == 4, "Funny platform") \end_layout \end_inset \end_layout \begin_layout Standard until then on namespace scope: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout #include BOOST_STATIC_ASSERT(sizeof(int) == 4) \end_layout \end_inset \end_layout \begin_layout Standard or without boost: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout template struct static_assert_helper; \end_layout \begin_layout Plain Layout template <> struct static_assert_helper {}; \end_layout \begin_layout Plain Layout enum { dummy = sizeof(static_assert_helper)}; \end_layout \end_inset \end_layout \begin_layout Standard or somewhat brutish without templates, in any function: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout const int d = sizeof(int) - 4; \end_layout \begin_layout Plain Layout switch(0) { \end_layout \begin_layout Plain Layout case 0: \end_layout \begin_layout Plain Layout case !(d*d): \end_layout \begin_layout Plain Layout break; \end_layout \begin_layout Plain Layout } \end_layout \end_inset \end_layout \begin_layout Standard Any of them in a .cpp file will break compilation as soon as sizeof(int) is not equal 4. Personally I prefer something like the third version (or the first, if using C++0x is allowed). \end_layout \end_deeper \end_deeper \begin_layout Itemize And one of mine: (vfr) \end_layout \begin_deeper \begin_layout Itemize On dynamics_casts \begin_inset Flex URL status open \begin_layout Plain Layout http://www.lyx.org/trac/changeset/35855 \end_layout \end_inset : \end_layout \begin_deeper \begin_layout Standard A dynamic_cast is necessary when: \end_layout \begin_layout Itemize the object to be casted is from an external library because we can't add Qxxx::asXxxx() to Qt e.g.: \end_layout \begin_deeper \begin_layout Itemize QAbstractListModel to GuiIdListModel, \end_layout \begin_layout Itemize QValidator to PathValidator, \end_layout \begin_layout Itemize QWidget to TabWorkArea, \end_layout \begin_layout Itemize QWidget to GuiWorkArea; \end_layout \end_deeper \begin_layout Itemize the object is to be casted from an interface to the implementing class, because the Interface does not know by whom it is implemented: \end_layout \begin_deeper \begin_layout Itemize ProgressInterface to GuiProgress, \end_layout \begin_layout Itemize Application to GuiApplication. \end_layout \end_deeper \begin_layout Standard A dynamic_cast can be replaced by: \end_layout \begin_layout Itemize already existing as***Inset() functions, e.g.: \end_layout \begin_deeper \begin_layout Itemize asHullInset(), \end_layout \begin_layout Itemize asInsetMath()->asMacro(), \end_layout \begin_layout Itemize asInsetText(); \end_layout \end_deeper \begin_layout Itemize A static_cast when we are sure this can't go wrong, e.g.: \end_layout \begin_deeper \begin_layout Itemize we are sure that CellData::inset->clone() is an InsetTableCell, \end_layout \begin_layout Itemize in cases where we explicitly check it->lyxCode(). \end_layout \end_deeper \end_deeper \end_deeper \begin_layout Bibliography \labelwidthstring Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "key-1" \end_inset S. Meyers. Effective C++, 50 Specific Ways to Improve Your Programs and Design. Addison-Wesley, 1992 \end_layout \begin_layout Bibliography \labelwidthstring Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "key-2" \end_inset Sutter, Herb. Exceptional C++: 47 engineering puzzles, programming problems, and solutions. ISBN 0-201-61562-2 \end_layout \begin_layout Bibliography \labelwidthstring Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "key-4" \end_inset Scott Meyers, C/C++ User's Journal (Vol.18,No.2) \end_layout \end_body \end_document