HNHacker News
TopNewBestAskShowJobs

thradams

223 karma · joined September 13, 2022

submissionscomments
thradams··on Cake – C23 and Beyond (2023)
It works in both ways. We can just tell the compiler to ignore some function. We can be also creative writing the code that at same time is good and makes the static analysis happy. A good sample is linked lists.

    #include <ownership.h> 
    #include <stdlib.h>
    #include <assert.h>
    #include <stdio.h>
    #include <string.h>

    struct node {
    char * owner text;
    struct node* owner next;
    };

    struct list {
    struct node * owner head;
    struct node * tail;
    };

    void list_append(struct list* list, struct node* owner node)
    {
    if (list->head == NULL) {
        list->head = node;
    }
    else {
        assert(list->tail->next == 0);
        list->tail->next = node; //ZERO OVERHEAD
    }
    list->tail = node;
    }

    void list_destroy(struct list* obj_owner list)
    {
    struct node * owner p = list->head;
    while (p) {
        struct node *  owner next = p->next;
        free(p->text); 
        free(p);
        p = next;
    }
    }

    void list_print(const struct list* list)
    {
    const struct node * p = list->head;
    while (p) {
        printf("%s ", p->text);
        p = p->next;
    }
    }

    int main()
    {
    struct list list = {};
    struct node  * owner p =  calloc(1, sizeof * p);
    
    if (p) {
        p->text = strdup("item1");
        list_append(&list, p);
    }

    list_print(&list);
    list_destroy(&list);
    }
thradams··on Cake – C23 and Beyond (2023)
Everything related to safety is on my list. (the list is big) I think big problems can be broken down into smaller ones.
thradams··on Cake – C23 and Beyond (2023)
The ownership works for non pointers. We can have integers (handles) that are owners. This allow custom allocators for instance. The concept of owner is some value that works as reference to an object and manages its lifetime.
thradams··on Cake – C23 and Beyond (2023)
Static analysis has a significant advantage over runtime checks for memory leaks, especially in code that is almost never executed, because bugs can remain hidden until they appear in production. The code where I found the bug last year was executed occasionally, and to create a unit test, it was necessary to integrate with another server. So it wasn't easy to check at runtime.

On the other hand static analysis will catch the error at first compilation even on those almost never executed code.

thradams··on Cake – C23 and Beyond (2023)
The real experience so far is the cake source itself.
thradams··on Cake – C23 and Beyond (2023)
The analysis can be disabled or silenced in some functions. the "static state" also can be override. (see the realloc sample)

Because this is C, the programmers can do wherever they want, but before it must do some negotiation with the static analysis.

thradams··on Cake – C23 and Beyond (2023)
Converting code can be challenging. The cake code has been successfully converted. null-checks are not ready, and something similar already happened to c#.

The experience is similar to changing a header file to use a const argument where previously the argument was non-const. This change will propagate everywhere.

I also think a similar experience is converting JavaScript to typescript. The type system will complain before it stabilizes.

thradams··on Cake – C23 and Beyond (2023)
"uninitialized memory" and "null checks" is part of flow analysis. UB and out of bound is not part of it.
thradams··on Cake – C23 and Beyond (2023)
The answer you can have the same source code and compile with gcc, but only cake is implementing the checks at this moment. The have the same source code compiling in any compiler a header ownership.h is used to define owner etc as empty macro. This strategy is used on cake source itself, that is checked with cake, but compiled with gcc msvc and clang.
thradams··on Cake – C23 and Beyond (2023)
Cake is a C23 front end, but it can also be used as a static analysis tool. The qualifiers can be empty macros then the same code can be compiled with gcc , clang and the static analysis of ownership can be using cake.

Inside visual studio for instance, we can have on external tools

C:\Program Files (x86)\cake\cake.exe $(ItemPath) -msvc-output -no-output -analyze -nullchecks

The main annotations are qualifiers (similar to const). C23 attributes were considered instead of qualifiers, but qualifiers have better integration with the type system. In any case, macros are used to be declared as empty when necessary.

The qualifiers and the rules can be applied to any compiler. Something harder to specify (but not impossible) is the flow analysis.

Sample of rule for compilers.

int * owner a; int * b; a = b;

we cannot assign view to an owner object. this kind of rule does not require flow analysis.

thradams··on Static Ownership Checks for C
Cake is a C23 Front End http://thradams.com/cake/index.html that is implementing static ownership checks.

Cake source itself is already using this feature that can be used and disabled with few macros.

The link is a tour explaining the concepts and usage of this feature.

thradams··on Experimental static ownership checks for C
I am currently experimenting with static ownership checks for C, aiming to provide guarantees that resources are released when necessary.

As this is a work in progress, bugs are expected. More flow analysis is required.

Despite that, you can still try out the checks online and observe some helpful error messages.

Simply visit the website below and select the 'Extension - Ownership' samples.

http://thradams.com/cake/playground.html

The C type system was extended with some new qualifiers. But only with flow analysis is possible to understand when variables goes out of scope or understand when the variables have been move before the end of scope. As I said, this is a work in progress but I am already very optimistic.

thradams··on Cake – A C23 compiler frond end written from scratch in C
To remove comments from source all you need is a tokenizer. You don't need all the tokens, just the "preprocessor tokens". For instance literal strings, ppnumbers ... Then /comments/ can be replaced with 1 space and //comments by \n
thradams··on Cake – A C23 compiler frond end written from scratch in C
Wow this is really bad!

This was my first topic here in hacker news.

I wasn't expecting all this traffic. Good to see and find more people interested in this kind of project.

I will be more careful in the future.

thradams··on Cake – A C23 compiler frond end written from scratch in C
Yes! I am Brazilian.
thradams··on Cake – A C23 compiler frond end written from scratch in C
The declaration of puts is missing at the stdio.h used by the web version. (If you output preprocessed you will see the declarations are there)

I will added it. Thanks.

Meanwhile you can add:

int puts( const char *str );

thradams··on Cake – A C23 compiler frond end written from scratch in C
My goal with the transpiler is not only the transpiler, although my front end had to be created differently of an normal compiler and preserve more tokens that could be discarded during the compilation. This also can be useful for a tool that does refactoring.. like renaming variables etc.. so in any case it it useful.

The new C23 language has a lot of features that makes your code not compile in previous C versions like attributes digit separators etc.. Someone may wants to create a new project in C23 and soon regret because the users of the code may need C99. This would be one use case, you can create a C23 code and have C99 versions of the same base code.

Unfortunately my transpiler is not "production ready" yet and I don't have IDE plugins etc.. that is required to make the tool more productive.

The other advantage, if we had a production ready transpiler with a IDE support etc.. it that we could use C23 and compile to C99 without having to wait for compilers like msvc to implements the standards.

Also some experimental features (like defer) can be used and you can distribute your code in standard C99. We have more freedom to use wherever we want and distribute a "readable" C99 code.

By the way most of the C transpilers or compilers generates C code only for immediate compilation. CFront was like that.

My transpiler have two modes one is for direct compilation and other is to distribute generated code.

Each mode has advantages and disadvantages.

thradams··on Cake – A C23 compiler frond end written from scratch in C
It's a front end. The backend implemented generates C code. I hope to have other backends in the future.
thradams··on Cake – A C23 compiler frond end written from scratch in C
The part that is the "transpiler" is visit.c and visit.h.

You can use it as reference to create different "visits". For instance, I am implementing a code format at "visitformat.c".

I have implemented a "naming convention checker" inside the parser, but it also can be a "visit".

Static analysis etc..can be a visit.

Inside the visit context you will find

struct ast ast;

That is the AST.

I would say the syntactic analysis parser is 100% complete C23.

Semantic analysis that is not 100%.

thradams··on Cake – A C23 compiler frond end written from scratch in C
Everything that is not part of C23 I annotated with "extension". For instance "Extension Defer" or "Extension Lambda" are not part of C23.
thradams··on Cake – A C23 compiler frond end written from scratch in C
Even having experience with C/C++, C preprocessor and C declarations took a long time. Some time to get used to the grammar as well.

A language without preprocessor and a simple grammar saves a lot time and you can go direct for the funny parts.

thradams··on Cake – A C23 compiler frond end written from scratch in C
thanks! :D
thradams··on Cake – A C23 compiler frond end written from scratch in C
This is my hobby project of a C23 Front End.

One of its unique features is the transpiler that can generate readable code, preserving macros and formatting.

See it online: http://thradams.com/web3/playground.html

← PreviousPage 2 of 2