Live data from Hacker News

Show HN: A simple garbage collector for C

github.com

51–60 of 62 posts

Re: Show HN: A simple garbage collector for C

#51
post #16
post #14

Earlier quoted context omitted.

Perhaps I'm misunderstanding this, but this doesn't solve the problem at all -- returning within the block statement wouldn't call the deferred expression, which is entirely the point of a defer statement, no? If control is guaranteed to reach the end of the block statement, of course; but requiring such a constraint would make this defer very handicapped. You have tons of function exit points and you most likely wan…

Yes, the only way I could imagine implementing a "proper" defer in C would be to use (like for most insane C hacks) setjmp/longjmp. I'm fairly sure it's explicitly forbidden by the Geneva Conventions though. Alternatively you might be able to use nested functions to guard against a stray return but that's not standard.

I guess you could do something like (couldn’t get Xcode’s clang to compile this, so it probably is buggy)

  static unsigned int __deferDepth = 0;

  #define RETURN return
  #define return ((__deferDepth == 0) ? RETURN : break do_return)

  #define DEFER(EXPR) \
    __label__ do_return; \
    for(int _tmp = 1; _tmp; _tmp = (do { \
      __deferDepth += 1; \
      EXPR; \
      __deferDepth -= 1; \
      break; \
      do_return: \
        RETURN; \
    }while(0);))
Nested DEFERs could get hairy, though (do you need a stack of __returnNotBreak values?), and there probably are issues if EXPR contains some nested loops with break or return.

Regardless, this isn’t C. Statement expressions (and __label_) are a gcc* extension, and if you’re willing to go there, __attribute__((cleanup)) seems the wiser route.

Re: Show HN: A simple garbage collector for C

#52
post #4

I just wish C had something like defer in go, That would cover most cases.

Check out Zig if you’re looking for a C replacement with a go style defer. It also interops about as well with C as C does.

I thought that depends on llvm though? Not to mention it doesn’t allow horizontal tabs which I dislike pretty intensely, different programming styles and environments work with different tab stops and it makes a lot of sense (IMO) to represent indentation with a single character.

Re: Show HN: A simple garbage collector for C

#53
post #49
post #44

Earlier quoted context omitted.

Writing a GC for C is pretty strange.

It’s really not. If you’re implementing a language runtime for language X, and the runtime is written in C, then writing the X GC actually means “writing a GC in C, for the subset of C allocations that represent X allocations.” E.g. Python objects are represented as PyObject values in CPython. Saying that Python is garbage collected is equivalent to saying PyObjects are garbage collected. Sure enough, PyObject contai…

I have to second GP, writing a GC for C is strange. Not because it is written in C, but for C. State of the art efficient and low latency GC pose requirements on the memory layout of allocated objects and often on the code generated to access those objects, i.e. memory fences of different kind. Some GCs like GHC's or some JVM GCs have special features integrated into the programming language semantics. Since, the semantics of C are basically fixed, the GC misses out on potential improvements and is only ever applicable to a strict subset of C programs.

Re: Show HN: A simple garbage collector for C

#54

Just out of interest for people not familiar with C, latest goings on there etc, what's the usecase where you'd want a garbage collector in C? My (very surface level) understanding was always the trade off for the increased manual effort of using C - manual memory management being one example - was that you could tailor your solution exactly to your usecase for increased performance / lower resource use. If you're go…

Typically, new garbage collected languages use the Boehm garbage collector (GC for C) in early versions, and then implement their own once they have time to fully optimize their runtime.

This is what Mono and Golang did. (They both used Boehm until they had time and resources to implement their own runtime-optimized GC.) I suspect Java did too, but I'm not sure.

In this case: "The original motivation for gc is my desire to write my own LISP in C, entirely from scratch - and that required garbage collection."

What basically happens is that gc (and Boehm) are "conservative garbage collectors." They treat all values in a data structure as a potential pointer, because they don't know the contents of the data structure. It's a good "quick and dirty" way to have garbage collection if you can accept the risk that some of your memory will remain uncollected if some of your data happens to have the same value as one of your pointers. In practice, it's a good tradeoff.

(Other tradeoffs are that you can't have things like real-time garbage collection, generational garbage collection, or compacting garbage collection.)

> If you're going for a garbage collector, why not also benefit from some of the increased language power/features of a higher level language?

Ironically, one of Boehm's use cases is looking for memory leaks. You basically #ifdef Boehm into a test build, and if a GC finds garbage, you know that you didn't free something correctly.

Re: Show HN: A simple garbage collector for C

#55
post #49

Earlier quoted context omitted.

It’s really not. If you’re implementing a language runtime for language X, and the runtime is written in C, then writing the X GC actually means “writing a GC in C, for the subset of C allocations that represent X allocations.” E.g. Python objects are represented as PyObject values in CPython. Saying that Python is garbage collected is equivalent to saying PyObjects are garbage collected. Sure enough, PyObject contai…

I have to second GP, writing a GC for C is strange. Not because it is written in C, but for C. State of the art efficient and low latency GC pose requirements on the memory layout of allocated objects and often on the code generated to access those objects, i.e. memory fences of different kind. Some GCs like GHC's or some JVM GCs have special features integrated into the programming language semantics. Since, the sem…

There's a subtlety here that I think you're missing.

The Hotspot JVM is a C++ program, CPython is a C program that implements the Python language. Both CPython and Hotspot mostly manage their respective memory in the usual styles of their host languages, but they still need some sort of host language representation for their target language objects.

AIUI, this is less obvious with the JVM (where the runtime manages to avoid a lot of host language allocations), but CPython has an explicit PyObject type, and every target language allocation corresponds to a host level allocation in some way. Because the lifecycle of these allocations in C is inextricably linked to the Python-level objects' lifecycle, you don't explicitly allocate/deallocate those manually on an individual level, you let the GC (Refcount in this case) handle that instead. It just turns out that "letting the GC do it" is really just "letting some other logic in my program do it". This means that implementing the Python GC corresponds exactly to implementing GC for PyObject objects at the C level.

Re: Show HN: A simple garbage collector for C

#56

Just out of interest for people not familiar with C, latest goings on there etc, what's the usecase where you'd want a garbage collector in C? My (very surface level) understanding was always the trade off for the increased manual effort of using C - manual memory management being one example - was that you could tailor your solution exactly to your usecase for increased performance / lower resource use. If you're go…

One thing that wasn't mentioned so far is that you may want to use garbage collection only for a portion of your program. You can mix manual malloc/free memory management (plus RAII-style automatic lifetimes) together with GC'd allocation in some parts of your program where you think the tradeoffs make sense.

Re: Show HN: A simple garbage collector for C

#57

Can it help with compiling Typescript to WASM? i.e. in https://github.com/AssemblyScript/assemblyscript

AssemblyScript already has tiny hybrid garbage collector (PureRC) which use deferred ARC and GC only for cyclic references: https://github.com/dcodeIO/purerc/blob/master/papers/Bacon03...

Re: Show HN: A simple garbage collector for C

#58
post #54

Just out of interest for people not familiar with C, latest goings on there etc, what's the usecase where you'd want a garbage collector in C? My (very surface level) understanding was always the trade off for the increased manual effort of using C - manual memory management being one example - was that you could tailor your solution exactly to your usecase for increased performance / lower resource use. If you're go…

Typically, new garbage collected languages use the Boehm garbage collector (GC for C) in early versions, and then implement their own once they have time to fully optimize their runtime. This is what Mono and Golang did. (They both used Boehm until they had time and resources to implement their own runtime-optimized GC.) I suspect Java did too, but I'm not sure. In this case: "The original motivation for gc is my des…

> Ironically, one of Boehm's use cases is looking for memory leaks. You basically #ifdef Boehm into a test build, and if a GC finds garbage, you know that you didn't free something correctly.

So a "garbage checker"? :) This is interesting, I never really thought about using it as a checking tool.

Post reply on HN