Live data from Hacker News

Show HN: My C compiler compiled itself

github.com

111–120 of 130 posts

Re: Show HN: My C compiler compiled itself

#111
post #107
post #50

Earlier quoted context omitted.

One might ask how you learned C (or python, or anything else) in the first place, if you can't be bothered to learn what the very simple $ The rest is just... of course you can reimplement make, or a subset of it, in python, python is turing complete after all. But why? make isn't that arcane. I'm sorry it uses the weirdly looking $@ and $ This is trivial in the sense that it's a part of any build system worth its sa…

I don't disagree that the concepts are simple; I'm arguing that the way they're conveyed in makefiles optimizes for the wrong thing by prioritizing tenseness over conveying useful information. The issue isn't that they "look weird", but that they give context that can be used to build additional concepts off of. A sibling reply to my comment mentions that `$ My point is that concepts being simple doesn't mean that th…

Lots of things optimize for terseness. Assembly, arithmetic/algebra, and any kind of shorthand in any kind of trade. That’s because the shorthand is usually easy enough to learn, and then provides value going forward.

You are perfectly capable of parsing “3+2*4”, I don’t have to always write it as “MULTIPLY 2 BY 4, ADD 3”. Similarly you would get pretty mad if instead of “ld” or “lda” you’d have to type “load register” or “load accumulator” each time. Those concepts are trivial once you understood them, you don’t need a constant reminder of what they expand to.

Doing so might get slightly more people to “start using the thing” in the very first step, but might also let many people look for a more terse alternative. And we don’t have to cater to any person who is really unwilling to learn.

Overall I find it hard to buy that you actually had much trouble with $I was hoping my introduction to Makefiles would be useful. If it was not, maybe I’m a bad educator after all.

Re: Show HN: My C compiler compiled itself

#112
post #110
post #69

Earlier quoted context omitted.

I've written a good amount of makefiles (and even one rather complex one.. before replacing it with a thing written in an actually sane language, bootstrapped by a stripped down version of the makefile), and I still mix up $@ $ or whatever else my brain comes up with. And this is coming from someone deep into array languages, which have entire sets of unicode glyphs. For how often one typically writes/looks at build…

Fair. But as said, in my experience, they remain useful and simple for a pretty long time. I usually always start out with a simple Makefile. Only sometimes do I start with or eventually switch to something else because of the projects’ needs, but for most stuff (even stuff where the project itself is complex, i.e. embedded kernel stuff where different units are pasted together and whatnot), relatively simple Makefil…

Aand that brings up another issue - that (and a good amount of things that will work as expected on the default -j1) breaks with -j4.

Apparently .WAIT and .NOTPARALLEL exist, which I couldn't find last time I needed something around this. Though for this unfortunately `make -j4 foo .WAIT bar` isn't allowed, but at that point separate make invocations is fine.

Re: Show HN: My C compiler compiled itself

#113
post #71
post #59

Earlier quoted context omitted.

Aha, so it doesn't know about void* being compatible with all (object) pointers, but so far just requires the pointers to match exactly? I see. Not sure why I was down-voted, I think that is ... not nice. :(

I don't think you can be downvoted, there's no downvote button

A beautiful example of Cunningham's Law! :)

Re: Show HN: My C compiler compiled itself

#114

Earlier quoted context omitted.

Redundant casts are really, really good at hiding errors... (And few people know that sizeof is a unary operator so the parentheses are rarely necessary. Dropping them reduces the visual noise => improves readability.)

> sizeof is a unary operator so the parentheses are rarely necessary I thought parentheses where still required for types, and are optional for variables. Even if that's not so, I still use them for types and avoid them for variables just to add one more cue about what's being sized.

Not "variables," but "expressions." In both C and C++, `sizeof` is a unary operator that applies to a postfix expression, so e.g. `sizeof a[0]` and `sizeof p->x` are both OK. This can theoretically be confusing, although the only examples I know are silly and/or easily fixed:

In C++, `p->pmf` has surprisingly low precedence, so `sizeof p->pmf` means `sizeof(p) ->* pmf`, which is ill-formed.

https://gcc.gnu.org/onlinedocs/cpp/Operator-Precedence-Probl... shows that "insufficiently hygienic" macros can also cause trouble, e.g. `-DINC(x)=x+1` means that `sizeof INC(1)` is `sizeof 1+1` which is `5`, not, as you might have naïvely expected, `sizeof (1+1)` which is `4`.

Extra parentheses can be used to deceive, too: `sizeof(0[p])` is the same as `sizeof(p[0])`, but `sizeof(0)[p]` is... also the same as `sizeof(p[0])` — not `p[sizeof(0)]` — because the postfix `[]` operator binds tighter than the prefix `sizeof` operator.

Oddly enough, the `alignof` operator officially applies only to types, as in `alignof(T)`; Clang, GCC, and EDG all do support `alignof expr`, but only as a non-standard extension.

Re: Show HN: My C compiler compiled itself

#115
post #112
post #110

Earlier quoted context omitted.

Fair. But as said, in my experience, they remain useful and simple for a pretty long time. I usually always start out with a simple Makefile. Only sometimes do I start with or eventually switch to something else because of the projects’ needs, but for most stuff (even stuff where the project itself is complex, i.e. embedded kernel stuff where different units are pasted together and whatnot), relatively simple Makefil…

Aand that brings up another issue - that (and a good amount of things that will work as expected on the default -j1) breaks with -j4. Apparently .WAIT and .NOTPARALLEL exist, which I couldn't find last time I needed something around this. Though for this unfortunately `make -j4 foo .WAIT bar` isn't allowed, but at that point separate make invocations is fine.

Another fair point. I think I'd use this:

    make restore & (make -j 20 kernel && make reset upload)
But in reality, the kernel target actually calls make anyway, so it's just in there. Depends on the exact situation.

Re: Show HN: My C compiler compiled itself

#117
post #105

Earlier quoted context omitted.

This is an amazingly good 2-minute introduction to makefiles. It would have been better without the last two sentences (and most of your comments on the topic). --- Something skipped over by your introduction (and most guides to makefiles) which very quickly either makes makefiles less short or much more complicated is header files. C files often depend on one or more header files that aren't system headers (this C c…

I did mention that in other comments, including the C preprocessor helping. make is completely language agnostic, so it cannot “guess” header dependencies. In make, you get the dependencies you specify (whether manual or generated), that’s what I wanted to show.

Make makes the easy part easy but the rest quite hard -- which I think you agree with.

It sure would be nice to have something like this:

  codegen/codegen.o: !codegen/codegen.c
     $(CC) -c $(CFLAGS) -o $@ $
'!' would run $(CC) with -MD to extract the header dependencies. Doing that back in 1995 would have increased the value and usability of GNU make immensely (and greatly reduced the need for all the other complexity it has).

Re: Show HN: My C compiler compiled itself

#118

Earlier quoted context omitted.

This is an excellent explanation of make! The only thing I will add is the slightly more abstract thought that make is meant to build files out of other files based on timestamps of the source files. And the target files can themselves become source files, which means that you can build dependency graphs. Lastly, it has “caching” built in: if bar.o is newer than bar.c, don’t rebuild it. If it doesn’t exist or is olde…

>Lastly, it has “caching” built in: A nitpick, but I don't think that should really be called caching, although it kind of is, in a looser sense. It's just comparing the file timestamps of the .o and .c files, and building the .o from the .c, if the .c is newer, or if the .o doesn't exist.

I mean it’s caching using a key derivation scheme which uses file names rather than file contents. It might not be sophisticated caching but it is caching.

Re: Show HN: My C compiler compiled itself

#119
post #57
post #54

Very cool, congratulations! I took a 2-second peek at the code, and just wanted to offer a small piece of advice that I think makes it better. Or two, really. Counting is hard. Instead of (this is from parser.c): apply_result *ret = (apply_result*)malloc(sizeof(apply_result)); apply the two common principles of DRY [1] and "don't cast the return value of malloc()" [2] and you get: apply_result *ret = malloc(sizeof *r…

This kind of condescending advice doesn't help anybody. Redundant casts, like redundant braces, white space, and a plethora of similar choices are stylistic more than anything else. If you really feel the need to give unsolicited coding style feedback maybe at least spend more than a few seconds looking at the code before you do so. Otherwise it's just rude.

this reads more like you're anxiously anticipating criticism bc you've been given feedback in a bad manner before. i interpreted nothing in OPs post, or condescending.

as someone who works largely in C and C++ codebases, these kinds of comments are gems, especially when i learn something.

what about it seems condescending? we are on a public forum, literally designed for discussion -- unsolicited perspectives, factual or otherwise -- are the norm, not some off-beaten, micro-transgression.

to reciprocate using a similar tone to the one you used with OP: i just do not understand how people find this offenses -- what are you so sensitive about?

Re: Show HN: My C compiler compiled itself

#120
post #59

Earlier quoted context omitted.

Aha, so it doesn't know about void* being compatible with all (object) pointers, but so far just requires the pointers to match exactly? I see. Not sure why I was down-voted, I think that is ... not nice. :(

I downvoted just because I thought it wasn't great advice. It makes the code incompatible with C++ compilers, and being able to compile C with C++ compiler is often useful. Also... it felt kind of... unnecessary? to tell someone who is making a compiler how to write basic code in the language they're writing a compiler for. It almost felt like telling an overweight medical student/doctor that he should avoid eating f…

Writing C code so won't compile with a C++ compiler is gods work.

Because C++ is why C can't have nice things.

Post reply on HN