shithub: scc

ref: 50d06031f803ff69ea1b44995d3bc47c6abc45ca
dir: /README/

View raw version
Derivations from standard C
===========================
This compiler is aimed to be being fully compatible with the C99 standard, but
it will have some differences:

- Type qualifiers are accepted but ignored.
  -----------------------------------------

Type qualifers make the type system ugly, and their uselessness add
unnecessary complexity to the compiler (and increased compilation time):
	- const: The definition of const is not clear in the standard.
	  If a const value is modified the behaviour is undefined
	  behaviour. It seems it was defined in order to be able to
	  allocate variables in ROM rather than error detection. This
	  implememtation will not warn about these modifications and
	  the compiler will treat them like normal variables (the standard
	  specifies that a diagnostic message must be printed).

	- volatile: This qualifier was added to the standard
	  to be able to deal with longjmp (local variables that are not
	  volatile have undefined state) and for memory mapped registers
	  or variables whose values are modified asynchronously. This can
	  be achieved with special pragma values though.
	  In the first case, it generates a lot of problems with modern
	  processors and multithreading, where not holding the value in a
	  register is not good enough (an explicit memory barrier is needed).
	  In the second case, this is non-portable code by definition
	  (depending on the register mapped), so it is better to deal with
	  it using another solution (compiler extensions or direct
	  assembler).

	- restrict: This qualifer can only be applied to pointers to
	  mark that the pointed object has no other alias. This qualifer
	  was introduced to be able to fix some performance problems in
	  numerical algorithms, where FORTRAN could achieve a better
	  performance (and in fact even with this specifier FORTRAN has a
	  better performance in this field). Ignoring it doesn't make the
	  compiler non-standard and in almost all applications the performance
	  will be the same.

- Function type names
  -------------------

C99 allows you to define type names of function types and write something
like:

int f(int (int));

Accepting function types in typenames (or abstract declarators) makes the
grammar ambiguous because it is impossible to differentiate between:

        (int (f))  -> function returning int with one parameter of type f
        (int (f))  -> integer variable f

If you don't believe me try this code:

int
f(int g())
{
	return g();
}

Function type names are stupid, because they are used as an alias
of the function pointer types, but it is stupid that something
like sizeof(int (int)) is not allowed (because here it should be
understood as the size of a function), but f(int (int)) is allowed
because it is understood as a parameter of function pointer type.

This complexity is not needed at all as function pointers fix all these
problems without this complexity (and they are the more usual
way of writing such code).

- Definition of variables with incomplete type
  ---------------------------------------------

C89 allows the definition of variables with incomplete type that
have external linkage and file scope. The type of the variable
is the composition of all the definitions find in the file. The exact
rules are a bit complex (3.7.2), and SCC ignores  them at this moment
and it does not allow any definition of variables with incomplete type.

If you don't believe me try this code:

struct foo x;

struct foo {
	int i;
};