which gets rid of one star. I’m not sure if I would go with your solution. It adds yet another abstraction (a structure) and I kind of like the look of the call sites now:
That call to max() would get ugly with all the structure references. Further more, the call site was reworked to that form in November of 2011. I’m not sure what that says about the code …
I’ve never actually seen three stars in practice. I sorta get ***argv example but I think there are other ways to write it, so nobody does that.
I’d be curious to see if anyone can point to a “justified” use of three stars in some real code. But honestly I think you can always rewrite it another way.
I’m usually a 1 star programmer, but recently I wrote some 2 star code which is kinda interesting:
static inline int J8EncodeOne(unsigned char** p_in, unsigned char** p_out,
int j8_escape) {
The input can move forward by 1 to 4 bytes because it also decodes UTF-8
The output can move forward by 1 to 7 bytes, the max escape being either \uffff or \u{1f}, plus NUL terminator
The reason it’s like this is because this code is meant to be reusable from BOTH C and C++. We have callers that use malloc() (slow!), callers that use our GC allocator, and a C++ std::string caller just for fun.
If it didn’t have to be decoupled from allocation, then I would pass a mutable std::string that you append to.
You can write this in other ways, but I think if both pointers change a variable amount at each step, AND you don’t want any allocation mixed with the logic, it’s the easiest and clearest way to write it, as long as you have a good test suite.
Now this pointer arithmetic is wildly unsafe – I wouldn’t have done it years ago. But this function has little control flow and ASAN hits all the bugs. You can get 100% coverage.
ASAN caught the bug where the max output is 7 and not 6, because sprintf() writes a NUL terminator too. (Not technically needed here, but it’s convenient to use sprintf for hex escapes).
Everybody’s a three star programmer, they just use structs to make it less confusing.
there you go, three stars right there, but it’s not confusing.
Three star programmers are just beginners who didn’t learn how to use structs yet.
that’s a great perspective, thanks for sharing. (c noob here)
When C compilers more widely became capable of passing and returning structs by value, no-star programming became much easier.
To reach the level of 2 star programmer, all you need is to write a C program with a
mainfunction, like this:Then, if you need to process your command line arguments, and deal for initial arguments beginning with
'-', you might write:Oh, but what if we want to move the flag processing into a function?
and then the definition will be:
Three star!
resubmitted today: last it was submitted 5 years ago, I am sure new members will surely enjoy reading this.
Not to be confused with Three Star Programmer, a (likely) Turing-complete esoteric language whose only instruction is, in C syntax:
Sadly, I’m a Three Star Programmer.
A couple comments hint at this, but none says it very explicitly. I would write this function with a struct as an out param:
https://github.com/spc476/mod_blog/blob/8eb3f660edd5a35c09616d058307e5a166052c99/src/blog.c#L335
would turn into
I like this style better because it clearly separates inputs and outputs. Right now there’s a both a return value and an out param.
At the call site that would be:
So yeah I think you never need three stars. I find it very confusing!
Since I wrote that, I did change the function:
which gets rid of one star. I’m not sure if I would go with your solution. It adds yet another abstraction (a structure) and I kind of like the look of the call sites now:
That call to
max()would get ugly with all the structure references. Further more, the call site was reworked to that form in November of 2011. I’m not sure what that says about the code …When I was in school I wrote a program with a
void*****once. I was tired, and code maintenance wasn’t really a thing I knew about yet.I’ve never actually seen three stars in practice. I sorta get
***argvexample but I think there are other ways to write it, so nobody does that.I’d be curious to see if anyone can point to a “justified” use of three stars in some real code. But honestly I think you can always rewrite it another way.
I’m usually a 1 star programmer, but recently I wrote some 2 star code which is kinda interesting:
https://github.com/oilshell/oil/blob/master/data_lang/j8.h (some comments are outdated, should fix that)
This is for C-escaping strings. On each call,
\uffffor\u{1f}, plus NUL terminatorThe reason it’s like this is because this code is meant to be reusable from BOTH C and C++. We have callers that use malloc() (slow!), callers that use our GC allocator, and a C++ std::string caller just for fun.
If it didn’t have to be decoupled from allocation, then I would pass a mutable
std::stringthat you append to.You can write this in other ways, but I think if both pointers change a variable amount at each step, AND you don’t want any allocation mixed with the logic, it’s the easiest and clearest way to write it, as long as you have a good test suite.
Now this pointer arithmetic is wildly unsafe – I wouldn’t have done it years ago. But this function has little control flow and ASAN hits all the bugs. You can get 100% coverage.
ASAN caught the bug where the max output is 7 and not 6, because sprintf() writes a NUL terminator too. (Not technically needed here, but it’s convenient to use sprintf for hex escapes).