scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

README (4791B)


      1 Compiling
      2 =========
      3 
      4 SCC is a portable toolchain that can be compiled on any UNIX system
      5 out of the box. It supports four main configuration options that
      6 can be passed to the command line:
      7 
      8 	- CROSS_COMPILE:
      9           Specify a prefix name for the tools called by the Makefile.
     10 
     11 	- HOST:
     12 	  Specify the host system to be used. Possible supported
     13 	  values are:
     14 
     15 		- unix (by default)
     16 		- bsd
     17 		- plan9
     18 
     19 	- CONF: Specify which version of libc to build.
     20 	  Once the build process completes only the target specified in
     21           CONF will be built. Supported values are:
     22 
     23 		- amd64-linux (default)
     24 		- amd64-darwin
     25 		- amd64-openbsd
     26 		- arm64-linux
     27 		- amd64-dragonfly
     28 		- amd64-netbsd
     29 		- arm32-linux
     30 
     31 	- TOOL: Specify the toolchain type to be used.  Possible
     32 	  supported values are:
     33 
     34 		- unix (by default)
     35 		- gnu
     36 		- gnu-darwin
     37 		- clang
     38 
     39 Deviations from standard C
     40 ===========================
     41 This compiler aims to be fully compatible with the C99 standard, but
     42 it will have some differences:
     43 
     44 - Type qualifiers are accepted but ignored.
     45   -----------------------------------------
     46 
     47 Type qualifiers make the type system ugly, and their uselessness adds
     48 unnecessary complexity to the compiler (and increased compilation time):
     49 
     50 	- const: The definition of const is not clear in the standard.
     51 	  If a const value is modified the behavior is undefined
     52 	  behaviour. It seems it was defined in order to be able to
     53 	  allocate variables in ROM rather than error detection. This
     54 	  implememtation will not warn about these modifications and
     55 	  the compiler will treat them like normal variables (the standard
     56 	  specifies that a diagnostic message must be printed).
     57 
     58 	- volatile: This qualifier was added to the standard
     59 	  to be able to deal with longjmp (local variables that are not
     60 	  volatile have undefined state) and for memory mapped registers
     61 	  or variables whose values are modified asynchronously. This can
     62 	  be achieved by using special pragma values though.
     63 	  In the first case, it generates a lot of problems with modern
     64 	  processors and multithreading, when not holding the value in a
     65 	  register is not good enough (an explicit memory barrier is needed).
     66 	  In the second case, this is non-portable code by definition
     67 	  (depending on the register mapped), so it is better to deal with
     68 	  it using another solution (compiler extensions or direct
     69 	  assembly). Since it is needed for the correct behaviour
     70 	  of portable programs that use longjmp, this specifier eventually
     71 	  will be implemented.
     72 
     73 	- restrict: This qualifier can only be applied to pointers that
     74 	  mark the pointed object and has no other alias. This qualifier
     75 	  was introduced to be able to fix some performance problems in
     76 	  numerical algorithms, where FORTRAN could achieve a better
     77 	  performance (and in fact even with this specifier FORTRAN has a
     78 	  better performance in this field). Ignoring it doesn't make the
     79 	  compiler non-standard and in almost all applications the performance
     80 	  will be the same.
     81 
     82 - Function type names
     83   -------------------
     84 
     85 C99 allows you to define type names of function types and write something
     86 like:
     87 
     88 int f(int (int));
     89 
     90 Accepting function types in type names (or abstract declarators) makes the
     91 grammar ambiguous because it is impossible to differentiate between:
     92 
     93         (int (f))  -> function returning int with one parameter of type f
     94         (int (f))  -> integer variable f
     95 
     96 If you don't believe me try this code:
     97 
     98 int
     99 f(int g())
    100 {
    101 	return g();
    102 }
    103 
    104 Function type names are stupid, because they are used as an alias
    105 of the function pointer types, but it is stupid that something
    106 like sizeof(int (int)) is not allowed (because here it should be
    107 understood as the size of a function), but f(int (int)) is allowed
    108 because it is understood as a parameter of function pointer type.
    109 
    110 This complexity is not needed at all as function pointers fix all these
    111 problems without this complexity (and they are the more common
    112 way of writing such code).
    113 
    114 - Definition of variables with incomplete type
    115   ---------------------------------------------
    116 
    117 C89 allows the definition of variables with incomplete type that
    118 have external linkage and file scope. The type of the variable
    119 is the composition of all the definitions found in the file. The exact
    120 rules are a bit complex (3.7.2) so SCC ignores them at this moment
    121 by simply not allowing any definition of variables with incomplete type.
    122 
    123 If you don't believe me try this code:
    124 
    125 struct foo x;
    126 
    127 struct foo {
    128 	int i;
    129 };
    130 
    131 - Variadic function alike macros
    132   ------------------------------
    133 
    134 The standard (C99 6.10.3 c 4) forces passing more parameters than
    135 the number of parameters present in the variadic argument list
    136 (excluding ...). SCC accepts a parameter list with the same number
    137 of arguments.
    138 
    139 #define P(a, ...) a
    140 
    141 P(1)