2023-06-27 11:09 from Nurb432 <nurb432@uncensored.citadel.org>
That sounds like a good thing, not a problem.
Yeah that sentence by itself is a good thing. What I meant to say is that they can't coordinate without knowing each other's implementation. A locked pthread_mutex being unrecoverable after a fork is just a broken design.
Anyway, it's just speculation on my part stemming from bad experiences I've had with GCC's __atomic_fetch_and_add and similar builtind. No idea whether _Atomic is implemented the same way. But I still stand by my point earlier that in my view, this multithreading stuff belongs in a platform lib, not in the language. Stop complicating my C! C99 is as good as it gets, it's only downhill from there.
K&R were remarkably good at getting things right that would continue to be right for a long time. I think I agree with you that C99 is as good as it gets.
// I do love my C99-style comments.
And I guess I will continue using pthread_mutex_*() for now.
// I do love my C99-style comments.
I actually don't :). I still stick to exclusively multiline comments even in c99 or above. In my opinion, the three big features that come with c99 are 1. named initializer lists (I don't know how I ever lived without this, it lets me write code that looks similar to how I write in Lua), flexible array members (I can live without it, but it is nice to avoid some ugly casts in some situations), and they coralled much of the project-specific typedef nonsense with stdint.h. Although inttypes.h is fucking retarded. They should have extended the printf/scanf DSL to understand the stdint.h types instead of giving us ugly macros. Oh, well.
Anyway, separate but tangentially related to the subject of comments: I have seen this practice in OCaml that they like to put their descriptive comments BELOW a function prototype. I like that, I think it looks nice. I don't understand why we don't do that in other languages. In other words, in your header you'd have:
int eat_shit(you *little_fucker);
/* This function makes little_fucker eat shit, and then it segfaults because why not. */
This seems so much more natural to me.
// I like C99 comments because
// they are great for multiline.
because they (go *behind, code, like_this);
and(furthermore, I_Like, to); // put a single comment to the right of a code line
/*
* In older code, I liked to line up the asterisks;
* and to do that properly you need two extra lines.
*/
so no one likes # for a comment then i guess?
( as odd as this sounds, this is part of implementing FORTH in Python, which of course its core is written in C..... )
def getWord (prompt="... ") :
global words
while not words :
try : lin = raw_input(prompt)+"\n"
except : return None
if lin[0:1] == "@" : lin = open(lin[1:-1]).read()
tokenizeWords(lin)
word = words[0]
words = words[1:]
return word
def tokenizeWords(s) :
global words # clip comments, split to list of words
words += re.sub("#.*\n","\n",s+"\n").lower().split() # Use "#" for comment to end of line
it should.
There is my formal request to whomever is maintaining C to add it.
:)
Thu Jul 13 2023 09:30:19 AM EDT from IGnatius T Foobar
I very much like '#' as a comment. But we're talking about C, which doesn't use it.
Ok, here's a great example of the kind of programming style that drives me batshit crazy.
// b_putroom() - back end to putroom() and b_deleteroom() // (if the supplied buffer is NULL, delete the room record) void b_putroom(struct ctdlroom *qrbuf, char *room_name) { char lowercase_name[ROOMNAMELEN]; char *aptr, *bptr; long len; aptr = room_name; bptr = lowercase_name; while (!IsEmptyStr(aptr)) { *bptr = tolower(*aptr); aptr++; bptr++; } *bptr='\0'; len = bptr - lowercase_name; if (qrbuf == NULL) { cdb_delete(CDB_ROOMS, lowercase_name, len); } else { time(&qrbuf->QRmtime); cdb_store(CDB_ROOMS, lowercase_name, len, qrbuf, sizeof(struct ctdlroom)); } }
What does it do? Well, if you read through it for a while, you eventually figure out that we're generating a key to store an item in a database, using the item's name converted to lower case as the database key. This is of course so that the item can be located in the database regardless of whether the user enters it in upper case, lower case, or mixed case.
Is it readable? Not very easily. Why is there pointer arithmetic here? I know who wrote this -- and if he ever reads this message, dude: your time is worth more than the computer's time -- and his intention was to shave off as many CPU cycles as possible. On an operation that only runs once in a while, on data objects less than 64 bytes long.
Now, I do realize that in my old days I did really inefficient things like
for (i=0; i<strlen(str); ++i) { do_something; }
And yes, that made it call strlen() on every iteration, which was bad. But I've since moved on to:
len = strlen(str); for (i=0; i<len; ++i) { do_something; }
That makes the code completely readable and obvious, at the expense of one call to strlen().
The moral of this story is: if you're doing pointer arithmetic, you'd better be doing something really hard.
In this day and age, understanding is more important than getting the n-th degree of efficiency . Its not 1978 anymore. We have resources to spare for the sake of supportability after you leave, or even want to look at your own code in 5 years.
( well unless you are doing embedded work, but even that is far more generous in resources these days )
Fri Jul 14 2023 08:18:11 PM EDT from IGnatius T FoobarThat makes the code completely readable and obvious, at the expense of one call to strlen().
But when I see pointer arithmetic for a simple string conversion function?
Dude, why didn't you just write it in assembly?
I realize I'm coming down pretty hard on someone who contributed a lot to the project. And my intention isn't to pick on a person, only on a technique.
I should have paid more attention when this stuff was being committed in the first place.
We grow and we pick up more skills and techniques. I think it's a truism that developing maturity in any engineering discipline sometimes involves learning when *not* to do the most clever thing you can think of. In software development that comes in the form of learning that your time is worth far more than the computer's time, especially if you are being paid. Whenever I see a linked list that I wrote 10 or 20 years ago, if I see that it's overly complex and introduces too many places where a bug can creep in, I now replace it with the elastic array class that I wrote. It's just so satisfying to see tons of cruft fall away, to see screenfuls of complex code being replaced with a few lines of readable code. Maybe the profiler is reporting that it took a few more milliseconds to complete. Maybe it uses a few more KB of memory. So what?
Microcode for the win! Everything else are just layers on top of that.
Once upon a time i could think in microcode, and moving bits around inside the CPU. Not anymore.. been too long. I guess i could get a FPGA out of the closet and start again where i left off in the 80s. Nah, no interest or energy.
Sat Jul 15 2023 12:12:31 PM EDT from IGnatius T Foobar
Dude, why didn't you just write it in assembly?
/dude: your time is worth more than the computer's time/ -- and his
Lol. As an embedded guy, this goes against every fiber of my being.
( well unless you are doing embedded work, but even that is far more
generous in resources these days )
It is more generous, and morons will STILL fill it up with shit! These days we have guys putting Python and JSON IPC in our products, and until recently I was one of the go-to guys who was expected to perform magic and make it fast and NOT use ALL of the memory.
I've never written in C on a machine that had less than 512 KB (again, except for the Arduino). Then again, the first unix I developed on was Xenix, with its "small model" compiler that barfed if you used more than 64 KB. Kids these days, they don't know how good they have it :)
i did embedded stuff for a while late 80s early 90s ( monitors, controllers, auto plant ) mostly on 8031's. Assembler, no fancy high level stuff. ( did write a forth for it, for my own amusement but never used it out in the plants )
Still have one of the boards from back then. I used to 'cheat' to save board space and piggybacked the ram/eprom.
All right, fellow nerds ... I've been writing in C for almost 40 years and apparently something changed when I wasn't looking. Someone please tell me when this became legal:
struct qux {
char foo[12345];
char bar[12345];
int baz;
};
struct qux myFunc(void) {
struct qux q;
strcpy(q.foo, "xxx");
strcpy(q.bar, "yyy");
q.baz = 3;
return(q);
}
For decades I have been laboring under the assumption that a function can only return types small enough to fit on a register; that is, in the case of a struct, you have to return a pointer to a struct, not the struct itself.
But now, I just tested the above, and it f***ing WORKED. And as far as I can tell from a web search, it's legal?!?
Assignment also seems to work; for example, myFunc() can end with
struct qux r;
r = q;
return(r);
I tested that and it worked too. When did that become legal?!? Also, I need to know, is this something that is now legal in the C language, or is it a hack that only works on GCC (like nested functions) ?
If this is legal, I've got a big pile of code that I can simplify. But only if it'll remain portable.
Ya that's legal, but unfurtunately it incurs the cost of a memcpy.
Mon Aug 21 2023 11:15:15 EDT from IGnatius T Foobar
All right, fellow nerds ... I've been writing in C for almost 40 years and apparently something changed when I wasn't looking. Someone please tell me when this became legal:
struct qux {
char foo[12345];
char bar[12345];
int baz;
};
struct qux myFunc(void) {
struct qux q;
strcpy(q.foo, "xxx");
strcpy(q.bar, "yyy");
q.baz = 3;
return(q);
}
For decades I have been laboring under the assumption that a function can only return types small enough to fit on a register; that is, in the case of a struct, you have to return a pointer to a struct, not the struct itself.
But now, I just tested the above, and it f***ing WORKED. And as far as I can tell from a web search, it's legal?!?
Assignment also seems to work; for example, myFunc() can end with
struct qux r;
r = q;
return(r);
I tested that and it worked too. When did that become legal?!? Also, I need to know, is this something that is now legal in the C language, or is it a hack that only works on GCC (like nested functions) ?
If this is legal, I've got a big pile of code that I can simplify. But only if it'll remain portable.