Live data from Hacker News

Let's Destroy C

gist.github.com

31–40 of 192 posts

Re: Let's Destroy C

#32
When I started learning C++, there was't a C++ compiler available for my Atari ST (late 80s), there was only Borland C. So instead I used the C preprocessor to emulate classes, virtual functions etcetera. Not everything could be implemented this way, but it looked like C++ close enough for me to learn it.

Re: Let's Destroy C

#34
post #25
post #10

GNU lambdas are incredibly evil. In order for lambdas to capture their environment and yet still be available as a function pointer, the compiler makes the stack executable and stores the trampoline code on the stack. C++ lambdas don't suffer from this problem.

GNU doesn't really have lambdas. This is an abuse of the compound statement macro. IIRC compound statements, like I've presented, don't use trampolines. Nested functions definitely do, but that isn't quite what we're doing here. GCC _should_ compile using descriptors for the compound statements that lambda is expanding to instead of using trampolines. gcc -fno-trampolines -I. examples/lambda.c Works. There's no tramp…

  #define lambda(ret_type, _body) ({ ret_type _ _body _; })
I found this one really fascinating, they're using both statement expression and nested functions. Their (reformatted) example of:

  int (*max)(int, int) =
    lambda(int, (int x, int y) { return x > y ? x : y; });
macro-expands to

  int (*max)(int, int) =
    ({ int _(int x, int y) { return x > y ? x : y;}; });
So they have a statement-expression with just one statement in it - the value of that statement is the value of the whole statement-expression. And the one statement inside the statement expression is a declaration of a nested function named _. Statement-expressions decay their return types, so that function gets converted to a function pointer. And thus your "lambda" is a pointer to a GCC nested function.

Re: Let's Destroy C

#35
post #32

When I started learning C++, there was't a C++ compiler available for my Atari ST (late 80s), there was only Borland C. So instead I used the C preprocessor to emulate classes, virtual functions etcetera. Not everything could be implemented this way, but it looked like C++ close enough for me to learn it.

That's basically how C++ was originally created, or the prototype, "C with Classes", albeit with a custom preprocessor. [0]

> In October of 1979 I had a pre− processor, called Cpre, that added Simula− like classes to C run-ning and in March of 1980 this pre− processor had been refined to the point where it supported onereal project and several experiments.

Recognising that you could do it that way is kinda awesome. Maybe not entirely uncommon, but you drafted a powerful bit of software yourself.

[0] http://www.stroustrup.com/hopl2.pdf

Re: Let's Destroy C

#37
post #27

You invented Ada.

Unsurprisingly, I adore Ada.

However, Ada's main benefits - the incredible type system, don't exist at all here. CNoEvil is a giant shotgun pointed directly between your legs.

Re: Let's Destroy C

#38
post #18

Earlier quoted context omitted.

Can you explain why?

To emphasise: This is about Bournegol. Nothing to do with this post. > Can you explain why? Because it isn't how most C libraries expect true/false to be defined. stdbool in C99 standardized things a bit, but before then what was generally accepted was: > true is 1 > false is !true (Often 0 in practice). Which means that any trivial: if(true) { ... } Won't work under Bournegol. Instead you _need_ to compare when doin…

Most cases I've seen accept anything as true as long as the LSB is 1, and quite strictly 0 as false. Everything else is up in the air. The value -1 is definitely true. :)

Re: Let's Destroy C

#40
A really good example of this is the implementation of Objective-C. I believe even the original C++ implementation by Bjarne Stroustrup were also C macros.
Post reply on HN