thradams / cake

Cake a C23 front end and transpiler written in C
http://thradams.com/cake/index.html
GNU General Public License v3.0
543 stars 23 forks source link

Feature: C23 improved tag compatibility missing implementation #187

Open ib00 opened 6 months ago

ib00 commented 6 months ago

Not many compilers (currently only gcc trunk) support C23 improved tag compatibility: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3037.pdf

Some data structures would be easier with this feature supported.

thradams commented 6 months ago

The idea for this feature is just remove the struct members from struct type. For instance

struct X { int i; };
void f(struct X { int i; } x){ }

generated code

struct X { int i; };
void f(struct X x) {}

What is missing is the comparison with the previous tag X.

ib00 commented 6 months ago

Here's an example that I have been plating with:

#define Array(TYPE) struct TYPE##Array {TYPE* elements; int count;}

void foo(Array(int) myArr) {
    // do something
}

int main() {
    Array(int) myInts;
    myInts.elements = (int*) (int[3]) {3, 2, 1};
    myInts.count = 3;
    foo(myInts);
    return 0;
}

This should compile with C23. At the moment only gcc trunk supports this.

thradams commented 6 months ago

There are some details. structs declared inside arguments does not have global scope. Then cake would have to introduce one declaration. or, if the user puts the like here

#define Array(TYPE) struct TYPE##Array {TYPE* elements; int count;}
#pragma expand Array

Array(int);

void foo(Array(int) myArr) {
    // do something
}

int main() {
    Array(int) myInts;
    myInts.elements = (int*) (int[3]) {3, 2, 1};
    myInts.count = 3;
    foo(myInts);
    return 0;
}

then the generated code would be


```c
#define Array(TYPE) struct TYPE##Array {TYPE* elements; int count;}
#pragma expand Array

struct intArray {int* elements; int count;};

void foo(struct intArray myArr) {

}

int main() {
    struct intArray myInts;
    myInts.elements = (int*) (int[3]) {3, 2, 1};
    myInts.count = 3;
    foo(myInts);
    return 0;
}