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