[HN Gopher] Advanced Metaprogramming in C: A select statement
___________________________________________________________________
Advanced Metaprogramming in C: A select statement
Author : pcr910303
Score : 44 points
Date : 2022-08-11 15:23 UTC (7 hours ago)
(HTM) web link (250bpm.com)
(TXT) w3m dump (250bpm.com)
| jstimpfle wrote:
| Metaprogramming should be limited, and metaprogramming in C is
| quite brittle and almost nobody really understand the execution
| model of he preprocessor. But, dismissing the preprocessor
| outright is too quick a conclusion. There are some clever and
| very practical uses of the preprocessor.
|
| - portability
|
| - generate strings from identifiers
|
| - Insert file and line of the call location (or other context)
| automatically when calling a function.
|
| - X-macros
|
| - Scopes with exit statement given at beginning, hacked using
| "for" statement and a condition that evaluates to true only the
| first time. A little bit brittle when the exit statement must not
| be skipped (goto, return).
|
| I'm sure there are more, but I'm too tired to think harder...
| Here is an example of the last category:
| #define TIMED_SECTION_(name, t) FOR_SCOPE(Timer t =
| start_timer(); print_passed_time(name, t)) #define
| TIMED_SECTION(name) TIMED_SECTION_(name, UNIQUE_NAME())
|
| Not giving the FOR_SCOPE() and UNIQUE_NAME() macros here for
| brevity. They add another 3-5 reusable lines. Use like this:
| TIMED_SECTION("foo the bar") { /* Do stuff,
| time spent in this scope will be measured and printed on scope
| exit. */ }
|
| Other more advanced languages can do some of the same things,
| sometimes more robustly, or not at all (X-macros is probably hard
| to replace for languages that are not LISP). But it typically
| comes at a cost in complexity, hard to use type systems,
| complicated semantics with edge cases... And they only allow you
| to do what is already built into the language!
| rrdharan wrote:
| http://libmill.org/ "is in an active auction".
|
| https://www.sav.com/auctions/details/1159199/libmill.org
|
| Insert some joke about the dangers of overly abusing the C
| precompiler...
| pcr910303 wrote:
| AFAIK It's http://libdill.org now :)
| s-video wrote:
| libmill and libdill are similar but different projects by the
| same author. I think he just let the libmill domain expire.
| What's funny is the site is a GitHub Pages site, so it's
| still there on the libmill repository, and _could_ be
| accessed at https://sustrik.github.io/libmill but it's
| configured to redirect to that expired libmill domain so it's
| inaccessible.
| mckirk wrote:
| On the one hand, I personally enjoy exercises like this, and the
| end result is quite pleasing to look at. On the other hand, the
| whole idea is kind of funny to me.
|
| In my experience, a proclivity to programming serious low-level
| code in C very much comes with an intense defensive reaction to
| things like "metaprogramming using the C precompiler". At least I
| still vividly the remember my co-workers' reaction to the C code
| I wrote as an intern, when I tried to be clever.
| comma_at wrote:
| libmill's goal was to be as close to Go as possible. If you
| look at it in that light, it's an accomplishment.
|
| Then came libdill, which created the whole "structured
| concurrency" movement and brought new concepts to light that
| are now being replicated in python, kotlin, java...
| jesse__ wrote:
| > programming serious low-level code in C
|
| I mean.. a lot of code that's written in C isn't particularly
| "low level" in the sense that it's optimizing for runtime or
| memory in any kind of outrageous way. A lot of C is very
| normal/straight forward code which can benefit greatly from
| metaprogramming due to the lack of language-level niceties.
|
| > I still vividly the remember my co-workers' reaction to the C
| code I wrote as an intern, when I tried to be clever.
|
| That's understandable. I'm highly skeptical of clever code
| anyone writes, including myself.
|
| I guess what I'm trying to say here is that metaprogramming and
| being clever aren't mutually intertwined ideas.
| quelsolaar wrote:
| I have thought a lot about meta programming and the best way to
| do it (I participate in the ISO C wg14) and I dislike macros,
| templets and every other attempt I have seen.
|
| The best solution I have found, disregarding of language, is to
| use the same language to write a program that generates the code
| you need.
|
| Then you can compile, and debug them separately using the same
| workflow, and each program can be clear and simple to read. Its
| not sexy or clever, but it works and anyone can understand what
| is going on. Almost always that turns out to be the most
| important thing.
| saghm wrote:
| > The best solution I have found, disregarding of language, is
| to use the same language to write a program that generates the
| code you need.
|
| Sounds like a pitch for lisp; I haven't really used any lisp
| variant much, but I always hear about people saying they
| basically write a program to generate their program rather than
| actually just solving the problem directly.
| WalterBright wrote:
| If you're using macros for metaprogramming in C, you've outgrown
| the language and are ready for a more powerful C replacement.
| Spivak wrote:
| Unless you need it to be in C because you're targeting
| platforms only supported by a C compiler or because you're
| writing a library and want different languages to have FFI.
| jxy wrote:
| Using initializer list would be much more readable without the
| atrocious macros.
| jesse__ wrote:
| Care to elaborate, or better yet link to a gist?
|
| Initializer lists aren't a thing in C, so I assume you're
| referring to array initialization :
| https://en.cppreference.com/w/c/language/array_initializatio...
|
| And with that said, I fail to see how using an initializer
| would have any effect on the end result.. unless of course you
| only read the first 150 words. Then your comment, while
| unnecessary, would make sense.
| david2ndaccount wrote:
| Initializer-lists are most definitely a thing in C and are
| part of the grammar. Check 6.7.9 of your C standard
| struct Foo { int x, y; }; struct Foo foo
| = {1, 2}; // ^ this is an initializer
| list.
|
| They also include designators, like: struct
| Foo foo = {.x=1, .y=2};
|
| The straw man struct initialization at the beginning of the
| article would be greatly improved with such a construct. Once
| you are no longer messing with macros, the rest of the
| article becomes a step too far.
|
| I assume the article was for c89, as c89 did not allow non-
| constant initializers. Any modern C compiler should compile
| c99 or newer code though.
| pid_0 wrote:
___________________________________________________________________
(page generated 2022-08-11 23:01 UTC)