[< back to index](../doc_index.md) # Differences from C ## Syntax * Block comments `/* */` are not supported, use line comments `//`. * You cannot put multiple statements on one line. Semicolons are allowed at the end of the line, but no code can follow them. * There are no `++` or `--` operators. Use `+= 1` and `-= 1`. * Pointer types are declared using the `pointer.` prefix, not `*` suffix. To dereference them, use `p[0]` instead of `*p`. * There is no unary `&` operator. Pointers to an object are acquired using the `.pointer` suffix. Raw addresses are acquired using the `.addr` suffix. The numeric values of the pointer and of the raw address may differ. * Operator precedence works differently. Bitwise and bit-shifting operators have the same precedence as arithmetic operators, and mixing different operators with the same precedence is usually forbidden. This prevents most ambiguities in bit-twiddling code, but requires care when porting code from or to C. * There is no `!` operator. The negation is expressed as the `not` function. * The modulo operator is written `%%`. As with `/`, it's only defined for unsigned division. * The `for` loops are range-based. Arbitrary, C-like `for` loops are not supported. * Variable declaration and initialization have to be separate. * Integer literals starting with zero and containing just digits are decimal, not octal. For octal literals, use the `0o` prefix. * String literals are not null-terminated by default. Use the `z` suffix for null-terminated strings. Note: this is the opposite of what KickC does! Keep this in mind when migrating KickC code to Millfork or the other way around. * In `if`, `do/while`, `while` and `for` statements, parentheses are not required, but braces are. The `else` branch also requires braces, unless the only statement in the `else` block is an `if` statement. * There has to be a space between many operators and character literals, as the parser may treat the apostrophe as a part of the operator. ## Preprocessor * The preprocessor cannot expand symbols to something more complex than an identifier or a literal. * The preprocessor cannot define symbols for use in other files. * The closest to C's `#define` is `#use`. Unlike `#define`, such definitions are not visible within the preprocessor. * Directives like `#use` and `#pragma` affect the entire file, not just the code after the directive. * The preprocessor cannot include files. ## Semantics * There is no automatic integer promotion. An operation of two bytes will yield a byte. For example: byte a byte b word w w = a * b may yield unexpected results. To prevent this, cast at least one argument: w = word(a) * b This issue applies mostly to the `*` and `<<` operators. * There is no padding in structs, except before fields whose type is a struct or a union with a non-trivial alignment.