Proposal
With the new ArrayType and the refactor of GlobalVariable the C-like code generation does not work as expected.
Therefore:
- fix casting to arrays (there is no cast into an array in C)
- fix pointer to an array into an explicit array pointer (see example below)
- fix printing of array elements (e.g. jump tables etc.) => maybe add a config option
- add new tests
To understand C arrays a bit better look at the following examples:
C arrays are used with a lot of syntax sugar.
All of these calls are equivalent, but are represented differently in assembly.
char a[] = "Some string";
char* b = "Some other string";
char c[] = "Some other other string";
char* d = c;
...
puts(a);
puts(b);
puts(c);
puts(d);
a/c will be real arrays (e.g. bytes in memory, and puts will load the address via lea), and b/d will be pointers to arrays in memory (e.g. puts will load the value of the pointer).
But:
- Technically a pointer must take the address of an variable, therefore:
char* b = c is actually char* b = &c
- The pointer itself points to an array, but char* is used for strings and chars. But C actually has a representation for pointers to arrays:
char (*e)[]. Therefore we can represent a pointer to an array as: char (*a)[] = &a;.
If we insert the value of the string, as it is possible for b, the expression would be: char (*a)[] = &"Some string"; which again is valid C code. The & could be dropped and is again valid c code.
The compiler will only generate type warnings when using these kind of arrays, because it will expect a const char*.
But because C can implicitly cast the array back to an const char, the code still works.
To conclude:
The lifter will now actually represent the correct relation ship, e.g. d will be a pointer to an char array.
Therefore we can (and should) represent this relation ship with the explicit style, e.g. char (*a)[] = &"Some string";.
(Maybe drop at least the & to be a bit more friendly)
Approach
.
Proposal
With the new
ArrayTypeand the refactor ofGlobalVariablethe C-like code generation does not work as expected.Therefore:
To understand C arrays a bit better look at the following examples:
C arrays are used with a lot of syntax sugar.
All of these calls are equivalent, but are represented differently in assembly.
a/c will be real arrays (e.g. bytes in memory, and puts will load the address via
lea), and b/d will be pointers to arrays in memory (e.g. puts will load the value of the pointer).But:
char* b = cis actuallychar* b = &cchar (*e)[]. Therefore we can represent a pointer to an array as:char (*a)[] = &a;.If we insert the value of the string, as it is possible for b, the expression would be:
char (*a)[] = &"Some string";which again is valid C code. The&could be dropped and is again valid c code.The compiler will only generate type warnings when using these kind of arrays, because it will expect a
const char*.But because C can implicitly cast the array back to an
const char, the code still works.To conclude:
The lifter will now actually represent the correct relation ship, e.g. d will be a pointer to an char array.
Therefore we can (and should) represent this relation ship with the explicit style, e.g.
char (*a)[] = &"Some string";.(Maybe drop at least the
&to be a bit more friendly)Approach
.