]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/README.style
update
[l4.git] / kernel / fiasco / src / README.style
1  Fiasco style guide
2
3  Michael Hohmuth
4
5 ; To generate a printable version of this document, please type 
6 ; cd ../doc/style; make
7
8 Introduction
9 ############
10
11 Motivation and intended audience
12 ================================
13
14 This document is meant as a quick reference to a number of guidelines
15 meant for existing and especially new Fiasco kernel developers.  
16
17
18 How to follow these rules: Metarules
19 ====================================
20
21 This document does not differentiate between strict rules and ``soft''
22 guidelines.  Also, when browsing the source code, you will notice a
23 large number of deviations from these rules (because most rules are
24 younger than the current kernel code).  In this sense, all rules are
25 ``soft.''
26
27 However, as the master guideline, when writing new code, please ensure
28 that the number of rule violations does not grow.  (In the future, we
29 might even enforce this property automatically when someone is
30 checking in code.)
31
32
33 Programming language, dialect, and subset
34 #########################################
35
36 Fiasco has been written in C++.  However, it uses C++ in a special
37 dialect supported by the Preprocess tool [Hohmuth: Preprocess].  In
38 effect, programmers do not need to write C++ header files, and do not
39 need to declare (member) functions -- Preprocess automates these
40 tasks.
41
42 We use some features of Preprocess for configuration
43 management---please refer to Section [Configuration-specific source code].
44
45 Preprocess lacks support for the following C++ features, which
46 therefore cannot be used in Fiasco source code (but can be used in
47 third-party source code used, i.e., can be included, by Fiasco):
48
49 * Name spaces --- use static class interfaces or global or static free
50   functions instead (Section [Singletons])
51 * Nested classes --- use forward-declared ``private classes'' instead
52 * '#ifdef' and 
53   '#if' on file top level, except for 
54   '#if 0' --- use
55   Preprocess' configuration features instead (Section
56   [Configuration-specific source code])
57
58 Some features of C++ are explicitly disallowed because Fiasco contains
59 no run-time support for them:
60
61 * Exceptions
62 * Run-time type identification and dynamic_cast
63
64 These features are always disabled on the compiler command line.
65
66 On the other hand, templates are allowed.  However, please keep in
67 mind that Fiasco's source code needs to be interpreted not only by the
68 latest version of GCC, but also by at least the two preceding stable
69 versions of GCC, _and_ ---more significantly---by the VFiasco project's
70 semantics compiler, which is a custom compiler _we_ (in a broader
71 sense of we) have to maintain.  Therefore, using advanced tricks such
72 as expression templates or partial specialization is strongly
73 discouraged.
74
75
76 Source-code organization and directory structure
77 ################################################
78
79 Subsystems
80 ==========
81
82 Fiasco consists of a number of subsystems; among them:
83
84 :KERNEL: The kernel proper.  This is the part that implements the L4
85   specification.
86
87 :ABI: ABI-specific definitions, mostly type definitions and accessor
88   functions.
89
90 :JDB: The built-in kernel debugger.
91
92 :BOOT: The bootstrapper.  This part sets up virtual memory, copies the
93   kernel to its standard virtual-address-space location (0xf0001000),
94   and runs the kernel.
95
96 Subsystems are defined in the Modules file, which is the main
97 configuration file for Fiasco's build system.  Please refer to
98 the build-system documentation [README] for more information on this
99 build system.
100
101 Directory structure
102 ===================
103
104 Subsystems usually reside in their own directory under src (the
105 exception being those subsystems which do not contain any source code,
106 but which exist only for maintenance purposes).
107
108 Inside each (source-code) subsystem directory such as kern, the
109 directory layout is as follows:
110
111 :kern/: Source files shared for all Fiasco-supported
112   architectures
113
114 :kern/shared/: Source files shared by more than one, but not
115   all architectures.
116
117 :kern/ia32, kern/ia64, kern/ux, and so on: Source files that are
118   specific for only one architecture.
119
120 Currently, hardware architectures is the only configuration dimension
121 that motivates moving a source file into a subdirectory.  In other
122 words, source files pertaining to a particular configuration option
123 (other than hardware architecture), but not another, are located in
124 one of the mentioned directories.
125
126 Source-file naming
127 ==================
128
129 Usually, source files belong to exactly one module, consisting of one
130 main C++ class plus, optionally, public utility functions, small
131 interface classes for exchanging data with the main class, and private
132 auxiliary classes and functions.  A module can be comprised of
133 multiple source files.  These source files all start with the name of
134 the module's main class, in all lower case (e.g., for class
135 Thread_state, file names start with the string "thread_state").  When
136 multiple source files implement one module, each file name (except for
137 the main file's) add a submodule-specific suffix, separated with a
138 dash (-).  For example:
139
140 * kern/thread.cpp
141 * kern/thread-ipc.cpp
142
143 Fiasco's build system mandates that all source files (of all
144 subsystems) have different names, even if they reside in different
145 directories.  To make file names different, our naming convention is
146 to add architecture-configuration strings to the file names, separated
147 by dashes (-).  For example:
148
149 * kern/thread.cpp
150 * kern/shared/thread-ia32-ux.cpp
151 * kern/ia64/thread-ia64.cpp
152
153 Occasionally, it is useful to separate configuration-specific code
154 into a source file of its own (see Section 
155 [Configuration-specific source code]).  In this case, the file name
156 contains the configuration string as a suffix, separated by dashes
157 (-).  For example:
158
159 * kern/thread-v4.cpp
160 * kern/thread-v2x0.cpp
161 * kern/ia32/thread-ia32-smas.cpp
162
163
164 Header files and the C++ preprocessor
165 =====================================
166
167 As Preprocess assumes the task of writing header files, programmers
168 should not add new header files.  The exception to this rule is that
169 header files are required when defining constants that are needed by
170 both assembly code and C++ code.
171
172 When using header files, these files must be protected from multiple
173 inclusions using include-file guards, as in the following example for
174 the file config_gdt.h:
175
176 !  #ifndef CONFIG_GDT_H
177 !  #define CONFIG_GDT_H
178 !  // File contents
179 !  #endif 
180
181
182 Configuration management
183 ########################
184
185 The configuration tool
186 ======================
187
188 The interactive configuration tool is started using "make menuconfig".
189 The tool creates two files, intended for inclusion in C++ code and in
190 makefiles:
191
192 :globalconfig.h: This file defines a preprocessor symbol for each
193   _enabled_ configuration option.
194
195 :globalconfig.out: This file defines a Make variable for set _each_
196   configuration option.  Variables for enables options are set to "y",
197   those for disabled options are set to "n".
198
199 Adding new configuration options
200 --------------------------------
201
202 Help texts for configuration options in the rules file (rules.cml) are
203 sorted by order in which the options appear in the menu defined at the
204 bottom of the file. New configuration options must add such a help text
205 describing what the config option does. After a new config option
206 has been added, define under which conditions the config option should
207 be suppressed, if any. It is generally a good idea to suppress config
208 options for architectures and configurations where the option is
209 meaningless. Options which can be suppressed for certain configurations
210 usually require consistency rules to ensure they are not left in an
211 undefined state from a previous selection.
212
213 An example suppression rule is:         
214 !  when UX suppress SERIAL
215 The corresponding consistency rule is:
216 !  require UX implies (SERIAL == n)
217
218 This ensures that 'SERIAL' is set to "n" when someone had previously chosen
219 'IA32' and 'SERIAL' set to "y" and then changes the architecture to 'UX'.
220
221 Do not forget to update the configuration templates in the directory
222 src/templates after modifying configuration options.
223
224 Class Config
225 ============
226
227 This class defines boot-time and constant configuration variables for
228 Fiasco.  
229
230 The constant variables can be derived from options the configuration
231 tool has written to globalconfig.h.  As a special exception, '#ifdef'
232 is allowed here.
233
234 Boot-time configuration variables can be derived from the kernel's
235 command line (class Cmdline).
236
237 Configuration-specific source code
238 ==================================
239
240 Single or multiple source files
241 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
242
243 Source code that is specific to one or a single combination of
244 configuration options can reside in a separate file or in the same
245 file as code for other configuration options.  The decision of which
246 works better is in the developer's discretion.  Developers should try
247 to combine logically cohesive code fragments in one source file, even
248 if the fragments are mutually exclusive.
249
250 Conditional compilation
251 ~~~~~~~~~~~~~~~~~~~~~~~
252
253 Using preprocessor constants and '#ifdef' for conditional compilation
254 is only allowed for source code passed to the assembler (assembly
255 files and header files meant to be included in assembly code).  In C++
256 source code, this style is discouraged, and Preprocess does not even
257 support it (for top-level conditional compilation).
258
259 Configuration-specific C++ code blocks are labeled using Preprocess'
260 configuration-tag feature with 'IMPLEMENTATION' and 'INTERFACE'
261 directives.  
262
263 This feature is available only on file top level.  Conditional
264 compilation inside function or class blocks is not allowed.  Instead,
265 programmers have the following options:
266
267 :For class definitions:
268   Use Preprocess' 'EXTENSION' feature to extend class data with
269   configuration-specific contents.
270
271 :For function definitions:
272   # Create a Boolean constant in class Config that depends on the
273     configuration option ('#ifdef' is allowed there; see Section
274     [Class Config]), and use the normal C++ 'if' statement to
275     conditionalize the code.  We rely on the C++ compiler's optimizer
276     to remove dead code.
277   # Factor out configuration-specific functions with a common
278     interface.
279
280
281 Compile-time polymorphism
282 =========================
283
284 Many configurable aspects of Fiasco are implemented as a set of
285 (member) functions that implement a given interface in a specific way.
286 However, unlike typical C++ programs, Fiasco usually does not define
287 these interfaces as abstract base classes and then derives
288 configuration-specific subclass implementations from them.  We have
289 deemed the overhead of virtual-function calls as too high in many
290 cases.  
291
292 Instead, in Fiasco these interfaces are not declared as virtual
293 functions, but as nonvirtual functions.  These functions are then
294 defined in configuration-specific 'IMPLEMENTATION' sections, which can
295 be combined in one file or spread across multiple files (see Section
296 [Configuration-specific source code]).  Preprocess assists in this
297 kind of compile-time polymorphism by allowing configuration-specific
298 inline functions and private member functions.
299
300 These interfaces do not need to be split out into separate classes.
301 It is often useful to have a part of a class interface that is
302 implemented in a configuration-specific way.
303
304 Usually, Preprocess assumes the task of copying (member-) function
305 declarations into a module's public header file, and this is our
306 preferred usage.  However, for interfaces that are implemented in a
307 configuration-specific source-code block, we make an exception: The
308 ``public'' interface (i.e., the interface used by generic client code,
309 which not necessarily needs consist of only public member functions)
310 can be declared and documented in the 'INTERFACE' section of the
311 corresponding module.  To prevent Preprocess from adding another
312 declaration, the definition needs to add the 'IMPLEMENT' directive.
313 The prerequisite is that the interface is implemented in an
314 'IMPLEMENTATION' section that depends on _more_ configuration options
315 than the 'INTERFACE' section containing the declaration.  For example:
316
317 !  INTERFACE:
318 !  
319 !  class Pic
320 !  {
321 !  public:
322 !    /**
323 !     * Static initalization of the interrupt controller.
324 !     */
325 !    static void init();
326 !    // ...
327 !  };
328 !  
329 !  IMPLEMENTATION[i8259]:
330 !  
331 !  IMPLEMENT 
332 !  void 
333 !  Pic::init()
334 !  {
335 !    pic_init(0x20,0x28);
336 !  }
337
338 Maintainer-mode configuration
339 =============================
340
341 Fiasco's build process can be instrumented with a number of checks
342 that ensure some of the rules defined in this document.  Fiasco
343 developers should enable this option in the interactive configuration
344 tool; the option is called 'MAINTAINER_MODE' (``Do additional checks
345 at build time'').
346
347 The checks enabled by this option include:
348 * Checking for mutual or circular dependencies between modules (see
349   Section [Dependency management])
350 * Checking for use of deallocated initialization data after
351   initialization time.
352
353
354 Dependency management
355 #####################
356
357 Fiasco has been designed to be configurable and robust.  A
358 precondition for achieving these properties is that modules and
359 subsystems can be removed from the kernel and tested in isolation,
360 which in turn depends on the absence of mutual or circular
361 dependencies between modules and subsystems.
362
363 Therefore, as a rule, these dependencies must be avoided.  Please
364 consult [Lakos: Large-scale C++ Software Design] for standard methods to
365 resolve circular dependencies.
366
367 The current dependency graph can be generated in text or graphics form
368 using "make DEPS" and "make DEPS.ps".
369
370
371 Source-code style and indentation
372 #################################
373
374 Naming conventions
375 ==================
376
377 In general, Fiasco developers despise the ugly
378 MixedCapsNamingConvention made popular by Java.  If you really must
379 use such names, please go hack some Java project, not Fiasco.  In
380 Fiasco, words in multi-word identifier names are generally separated
381 with underscores, with the sequencing words starting with a lowercase
382 letter or a digit (the only exception being preprocessor symbols).
383 Examples:
384
385 !  Funky_type
386 !  thread_id
387 !  Thread_ready
388 !  _current_sched
389 !  _thread_0
390
391 In particular, the conventions are as follows:
392
393 * Type names (class names, typedef names, enum names) all start with a
394   capital letter.  Examples: 'Thread', 'Jdb', 'Boot_info'
395
396 * Function names (both member functions and free functions) start with
397   a lowercase letter.  Examples: 'fpage_map()', 'ipc_send_regs()'
398
399 * Nonstatic member variables start with an underscore (_).  Examples:
400   '_mode', '_ready_time'
401
402 * Other variables (including static member variables, global and local
403   variables, function-argument names) start with a lower-case letter.
404   Examples: 'preempter', 'cpu_lock'
405
406 * Enumeration constants start with a capital letter. Examples:
407   'Thread_ready', 'Page_writable'
408
409   The Fiasco architecture board has declared that having the same
410   naming convention for types and constants is not confusing.
411
412 * Preprocessor-symbol identifiers are all-uppercase and start with a
413   letter.  As with all other identifiers, multiple words are separated
414   using underscores.  Examples: 'THREAD_BLOCK_SIZE', 'CONFIG_IA32_486'
415
416   Please note that preprocessor constants are deprecated and allowed
417   only in assembly files and header files meant to be included in
418   assembly code (see Section [Constant definitions]).
419
420 (For file-naming conventions refer to Section [Source-file naming].)
421
422 Comments
423 ========
424
425 All comments must be in English.  American / Aussie / Kiwi English are
426 OK, too, but Pidgin English or Denglisch are not.
427
428 Doxygen comments
429 ~~~~~~~~~~~~~~~~
430
431 Please document at least all interfaces of all classes that are meant
432 for client-code use.  These interfaces usually include all public and
433 protected member functions and all nonstatic free functions, but
434 possibly more if there is a private interface implemented by
435 configuration-specific code.
436
437 The interface documentation belongs to the function definition, except
438 if configuration-specific functions (with the 'IMPLEMENT' directive)
439 are declared in an 'INTERFACE' section.  In the that case, the
440 documentation belongs to the declaration.
441
442 Please use Doxygen's Javadoc-like style (the style using '@' instead
443 of backslashes) to document your interfaces.  Fiasco's documentation
444 is generated using Doxygen's auto-brief feature, so '@brief'
445 directives are unnecessary [Heesch: Doxygen Manual].
446
447 Comment style
448 ~~~~~~~~~~~~~
449
450 The style of multi-line comments is not prescribed, but please be
451 consistent within one source file.  All of the following forms are
452 OK:
453
454 !  /** The foo function.
455 !   *  This function frobnifies its arguments.
456 !   */
457 !
458 !  /** 
459 !   *  The foo function.
460 !   *  This function frobnifies its arguments.
461 !   */
462 !
463 !  /** The foo function.
464 !      This function frobnifies its arguments.
465 !  */
466
467 Marking incomplete code
468 ~~~~~~~~~~~~~~~~~~~~~~~
469
470 Please use the token 'XXX' inside a comment to mark broken or
471 incomplete code.
472
473 Module-level rules
474 ==================
475
476 Singletons
477 ~~~~~~~~~~
478
479 Singleton objects (classes that will be instantiated only once) should
480 be implemented as static class interfaces instead of a normal
481 instantiable class in order to save kernel-stack space (the this
482 pointer does not need to be passed to these classes).  However,
483 developers should use normal classes when it is foreseeable that the
484 class needs to be instantiated multiple times in the future, for
485 instance to support SMP machines.
486
487 Constant definitions
488 ~~~~~~~~~~~~~~~~~~~~
489
490 Constants should generally only be defined in enumerations.
491 Preprocessor constants are discouraged except for source code passed
492 to the assembler (assembly files and header files meant to be included
493 in assembly code).
494
495 In C++ code, preprocessor constants must not be used for conditional
496 compilation using '#ifdef' and friends (see Section 
497 [Conditional compilation]).
498
499 Bit-field types
500 ~~~~~~~~~~~~~~~
501
502 When implementing a binary interface that has been specified in terms
503 of bits of machine words (such as the L4 ABI or a device interface),
504 it is a bad idea to implement the interface using bit-field types,
505 unless the interface is architecture-specific.  The reason is that the
506 assignment of bit-field members to bit offsets is both
507 compiler-dependent and architecture-dependent.  If bit fiddling is
508 required, please define a class that wraps an integral type (such as
509 'unsigned') and manipulate the bits using bit-and and bit-or
510 operators.
511
512 Bit-field structures are OK when the exact order of bits in the type's
513 memory representation does not matter.
514
515 Block-level rules
516 =================
517
518 Assertions
519 ~~~~~~~~~~
520
521 Use assertions generously.
522
523 Fiasco supports two kinds of runtime assertions: 'assert' and 'check'.
524 Both cause a kernel panic when their argument evaluates to false.
525
526 The first, 'assert', works just like 'assert' in standard C.  It can
527 be removed from the build by defining the preprocessor symbol 'NDEBUG'
528 and therefore must not include code that has side effects.
529
530 When side effects are desired, use 'check' instead of assert.  The
531 contents of this macro are not optimized away with 'NDEBUG' -- only
532 the error-checking code is.
533
534 Common idioms
535 ~~~~~~~~~~~~~
536
537 * Endless loops are programmed like this:
538
539   !  for (;;)
540   !    // do stuff
541
542 * Sometimes a private inline function is desired, for example if it
543   needs to be wrapped by a stub that is callable from assembly code.
544   In this case, use 'inline NOEXPORT' to avoid having to specify a
545   lengthy 'NEEDS[]' directive for the inline function:
546
547   !  extern "C" 
548   !  void
549   !  asm_callable_stub (Thread* t)
550   !  {
551   !    t->do_stuff();
552   !  }
553   !
554   !  PRIVATE inline NOEXPORT
555   !  Thread::do_stuff ()
556   !  {
557   !    // ...
558   !  }
559
560 * Macros are discouraged.  Use inline functions instead.
561
562 * If you really, absolutely have to define a macro, please make sure
563   it can be used as single-statement blocks after 'if', 'else', and
564   the like, by wrapping it like this:
565
566   !  #define foo(x)  do { /* your stuff */ } while (0)
567
568 Rules for spacing, bracing, and indentation
569 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
570
571 If not specified more precisely in this standard, the GNU Coding
572 Conventions for spacing and bracing apply ([GNU Coding Standards],
573 Section 5.1).
574
575 * The tabulator size is 8.  A tabulator can always be replaced with
576   spaces that lead to the next tab stop.
577
578 * The maximum line length is 80.  If a code line becomes longer than
579   80 characters, it must be broken into shorter lines.  If line length
580   becomes excessive, developers should factor out utility functions.
581
582 * The indentation increment is 2 spaces.
583
584 * In function definitions, put both the return type and the function
585   signature on a line by themselves.  Example:
586
587   !  PUBLIC inline
588   !  void
589   !  Preemption::set_preempter (Receiver *preempter)
590   !  {
591   !    // ...
592   !  }
593
594 * Put whitespace before each opening parenthesis, except if it is
595   preceded by another opening parenthesis.  Put whitespace after each
596   closing parenthesis, except if it is followed by another closing
597   parenthesis or a comma or semicolon.  As a special exception, you do
598   not need to put a space between a function name and the
599   function-call operator.
600
601   !  a = f (b(), sin ((x + y) * z));
602
603 * Do not wrap the argument to the 'return' statement into parentheses.
604
605 * Opening and closing braces ('\{', '\}', including the form '\};')
606   always reside on a line of their own.  The braces are indented for
607   nested code blocks, but not for type and function definitions.  The
608   braced content is always indented with respect to the braces.
609
610   Goto labels are back-indented 1 space, class-access specifiers
611   (public, protected, private) are back-indented 2 spaces.
612
613   !  class Thread
614   !  {
615   !  public:
616   !    enum Thread_state
617   !    {
618   !      Thread_invalid, Thread_running
619   !    };
620   !
621   !    int _prio;
622   !  };
623
624   !  PUBLIC
625   !  void
626   !  Thread::stuff ()
627   !  {
628   !    if (receiver()->ipc_try_lock (this) == 0)
629   !      {
630   !        do_stuff();
631   !      }
632   !  }
633
634   As an exception, if a function definition fits into a single line,
635   the whole function can be defined in one line.  This style can aid
636   readability when defining many small functions in a row.
637
638 * Curly braces around single-statement code blocks for 'if', 'while',
639   'do', and 'for' are optional, except if the control expression(s) of
640   these statement spans more than one line, the statement following it
641   must be braced.
642
643 * Spacing inside expressions is not prescribed.  Please do something
644   sensible to save us from adding more rules to this document.
645
646 ; Fiasco style rules
647
648 ; Y Directory organization
649
650 ; Y Naming: Classes, methods, constants
651
652 ; Y No exceptions, no RTTI
653
654 ; Y Singleton objects as static class interfaces, to save stack space
655
656 ; Y no preprocessor variables -- use enums
657
658 ; Y IMPLEMENT nur für definitionen in spezielleren Subsections
659
660 ; Y config class vs configuration management
661
662 ; Y header files: unusally not.  otherwise, multi-inc protection
663
664 ; Y assert, check
665
666 ; Y Max. 80 Zeichen pro Zeile
667
668 ; Y Doxygen-Style
669
670 ; Y Doxygen: Bei deklarierten Memberfunktionen (mit IMPLEMENT
671 ;   implementiert) kommt die Doku vor die Deklaration
672
673 ; Y Member-Vars: _member_name
674 ;   Klassen:     Class_name
675 ;   Konstanten:  Constant_name
676
677 ; Y XXX-Kommentare
678
679 ; Y wann eigenes Quellfile, wann mehrere IMPLEMENTATION-Sections in
680 ;   einem File?
681
682 ; Y Funktionname an Zeilenbeginn, Name/Parameter auf einer Zeile
683
684 ; Y Rückgabetyp auf Extra-Zeile
685
686 ; Y Einrücke-Standards
687 ;   . Enums
688
689 ; Y Endlosschleife: for (;;)
690
691 ; Y Makros: use do {} while (0);  (else-kompatibel)
692
693 ; Y Use inline NOEXPORT für lokale Inlines  (ohne NEEDS)
694
695 ; - kleine Interfaces erwünscht -- minimiere PUBLIC
696
697 ; Y Makros vermeiden
698
699 ; Y Konstanten als enums
700
701 ; Y cyclic dependencies, 
702 ;
703 ; - initcalls
704 ;
705 ; - boolean return values -- bool vs Mword, maybe a new type Bool?
706 ;
707 ; - "Thread*" t vs "Thread *t"
708 ;
709 ; - Style of CVS commit messages
710 ;
711 ; - Code duplication avoidance
712 ;
713 ; - C++ default parameters -- discouraged?
714 ;
715 ; - Passing structures as const structure&
716
717 ; - Makeconf.local: the place to set CC, CXX
718 ;
719 ; - Sort IMPLEMENTATION[xyz] sections alphabetically: ARM vor IA32 vor
720 ;   UX, V2 vor V4 vor X0 bzw. V2,X0 vor V4.
721 ;
722 ; - declaration/IMPLEMENT are not for documentation purposes, which
723 ;   would not work anyway; use the files in auto/ or Doxygen.
724
725 ; ----------------------------------------------------------------------
726
727 ; René:
728
729 ; Was mir am Anfang nicht klar war:
730
731 ; Y Namenskonvention, member mit _foo, Klassen mit Grossbuchstaben
732 ;   beginnen & co, Namen allg.
733
734 ; Y Comments englisch only
735
736 ; Y Klammersetzung!! Auch wo man Klammern weglassen soll!
737
738 ; - IMPLEMENT vs PUBLIC, PRIVATE, PROTECTED
739
740 ; Erwaehnenswert waere noch fuer Neuanfaenger
741
742 ; Y keine ifdefs
743
744 ; - vieleicht Waechter-Style:
745 ;   also nicht
746
747 ;       if foo
748 ;               if bar
749 ;                       if foobar
750
751 ;   sondern eher
752 ;       if !foo
753 ;               return
754 ;       if !bar
755 ;               return 
756 ;   usw.
757
758 ; Y Vieleicht sollten wir die maximale Einruecktiefe begrenzen. Ich bin fuer
759 ;   3-4. Ich weis das vieles im Code noch nicht so ist, aber man kann ja mal
760 ;   anfangen.
761
762 ; - Generic vs Arch.-spezifische Sachen, zB im generic kein regs()->ecx &
763 ;   co.
764
765
766
767 ;   Assemblermacros:
768 ;   Bis vor kurzen habe ich noch die #define Version genommen.
769 ;   Macht sich aber richtig ******* beim schreiben.
770 ;   Habe jetzt mein Zeug auf .macro umgestellt, sieht erheblich freundlicher
771 ;   aus.
772
773 ;   Ein paar hinweise allg zu Assembler, wann man lieber
774 ;   Funktionen/gemeinsamen Code sollte und wann Makros.
775
776 ;Local Variables:
777 ;mode:flyspell
778 ;ispell-local-dictionary: "american"
779 ;comment-start: ";"
780 ;comment-start-skip: "; *"
781 ;End:
782
783 ; LocalWords:  accessor Hohmuth tex pdflatex README Preprocess GCC polymorphism
784 ; LocalWords:  nonvirtual instantiable NDEBUG Doxygen's Doxygen XXX Javadoc cpp
785 ; LocalWords:  NOEXPORT Metarules ifdef