Live data from Hacker News

Weekend projects: getting silly with C

lcamtuf.substack.com

41–50 of 118 posts

Re: Weekend projects: getting silly with C

#41
post #28

Earlier quoted context omitted.

The libglib-dev with gcc is very handy for toy projects, but only _after_ students try to write their own versions: https://docs.gtk.org/glib/data-structures.html It could be fun to do a lab summary after the lists and hashes introduction. Have a wonderful day, =)

I absolutely I agree that learning to create you own abstractions is an incredible useful skill. It depends though. For a programming course this makes absolutely sense. But for applied problems in, say, biomedical engineering, this does not work. Many students know only a bit of Python, and then it is too much and "too inconvenient" to start from scratch in C. With Python they have a lot of things more easily availa…

Python like Basic abstracted far to many details away from students, and trying to convince people they need to know how a CPU works later is nearly impossible.

In general, digging deep enough down a stack, and it drops back into the gsl:

https://www.gnu.org/software/gsl/

Indeed, first month attrition rates for interns at some companies is over 46%. =3

Re: Weekend projects: getting silly with C

#42
post #38

This reminds me of some silly C code I once wrote for fun, which counts down from 10 to 1: #include // compile & run: gcc -Wall countdown.c -o countdown && ./countdown int n = 10; int main(int argc, char *argv[]) { printf("%d\n", n) && --n && main(n, NULL); } Python version: import sys # run: python3 countdown.py 10 def main(n:int): sys.stdout.write(f"{n}\n") and n-1 and main(n-1) main(int(sys.argv[1])) Shell version…

I don't think I've ever thought of explicitly calling main(). Made me chuckle.

Re: Weekend projects: getting silly with C

#43
post #40

Earlier quoted context omitted.

The time-travelling UB interpretation was popularized by this blog post about 10 years ago [1]. I'm not enough of a specification lawyer to say that this is definitely true, but the reasoning and example given there seems sound to me. [1] https://devblogs.microsoft.com/oldnewthing/20140627-00/?p=63...

Yes, random blog posts did a lot of damage here. Also broken compilers [1]. Note that blog post is correct about C++ but incorrectly assumes this is true for C as well. [1]. https://developercommunity.visualstudio.com/t/Invalid-optimi...

I'm inclined to trust Raymond Chen and John Regehr on these matters, so if you assert that they're incorrect here then a source to back up your assertion would help your argument.

Re: Weekend projects: getting silly with C

#44
post #40

Earlier quoted context omitted.

The time-travelling UB interpretation was popularized by this blog post about 10 years ago [1]. I'm not enough of a specification lawyer to say that this is definitely true, but the reasoning and example given there seems sound to me. [1] https://devblogs.microsoft.com/oldnewthing/20140627-00/?p=63...

Yes, random blog posts did a lot of damage here. Also broken compilers [1]. Note that blog post is correct about C++ but incorrectly assumes this is true for C as well. [1]. https://developercommunity.visualstudio.com/t/Invalid-optimi...

> Also broken compilers [1].

The issue you linked to is not a counter example because, as the poster said, g may terminate the program in which case that snippet does not have undefined behaviour even if b is zero. The fact that they bothered to mention that g may terminate the program seems like an acknowledgement that it would be valid to do that time travelling if it didn't.

> Note that blog post is correct about C++ but incorrectly assumes this is true for C as well.

Presumably you're referring to this line of the C++ standard, which does not appear in the C standard:

> However, if any such execution contains an undefined operation, this International Standard places no requirement on the implementation executing that program with that input (not even with regard to operations preceding the first undefined operation).

I looked at every instance of the word "undefined" in the C standard and, granted, it definitely didn't have anything quite so clear about time travel as that. But it also didn't make any counter claims that operations before are valid. It pretty much just said that undefined behaviour causes behaviour that is undefined! So, without strong evidence, it seem presumptuous to assume that operations provably before undefined behaviour are well defined.

Re: Weekend projects: getting silly with C

#46
post #38

This reminds me of some silly C code I once wrote for fun, which counts down from 10 to 1: #include // compile & run: gcc -Wall countdown.c -o countdown && ./countdown int n = 10; int main(int argc, char *argv[]) { printf("%d\n", n) && --n && main(n, NULL); } Python version: import sys # run: python3 countdown.py 10 def main(n:int): sys.stdout.write(f"{n}\n") and n-1 and main(n-1) main(int(sys.argv[1])) Shell version…

Nitpick: you could replace sys.stdout.write(f"{n}\n") with print(n). The current code looks very much like it was written for Python 2 (apart from the f string!), where print was a statement. As of Python 3, print is just a regular function. It returns None, which is falsey, so you'd also need to change your first "and" to an "or".

Re: Weekend projects: getting silly with C

#47
post #40

Earlier quoted context omitted.

Yes, random blog posts did a lot of damage here. Also broken compilers [1]. Note that blog post is correct about C++ but incorrectly assumes this is true for C as well. [1]. https://developercommunity.visualstudio.com/t/Invalid-optimi...

> Also broken compilers [1]. The issue you linked to is not a counter example because, as the poster said, g may terminate the program in which case that snippet does not have undefined behaviour even if b is zero. The fact that they bothered to mention that g may terminate the program seems like an acknowledgement that it would be valid to do that time travelling if it didn't. > Note that blog post is correct about…

The poster is me. You are right that this is not an example for time-travel. There aren't really good examples for true time travel because compilers generally do not do this. But my point is that with compilers behaving like this, people might confuse this for time-traveling UB. I have certainly met some who did and the blog posts seems to have similar examples (but I haven't looked closely now).

Note that I am a member of WG14. We added more clarification to C23 to make clear that this is not a valid interpretation of UB, see here: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf

Re: Weekend projects: getting silly with C

#48
post #43
post #40

Earlier quoted context omitted.

Yes, random blog posts did a lot of damage here. Also broken compilers [1]. Note that blog post is correct about C++ but incorrectly assumes this is true for C as well. [1]. https://developercommunity.visualstudio.com/t/Invalid-optimi...

I'm inclined to trust Raymond Chen and John Regehr on these matters, so if you assert that they're incorrect here then a source to back up your assertion would help your argument.

I am a member of WG14. You should check the C standard. I do not see how "time-travel" is a possible reading of the definition of UB in C. We added another footnote to C23 to counter this idea:

https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf "Any other behavior during execution of a program is only affected as a direct consequence of the concrete behavior that occurs when encountering the erroneous or non portable program construct or data. In particular, all observable behavior (5.1.2.4) appears as specified in this document when it happens before an operation with undefined behavior in the execution of the program."

I should point out that compilers also generally do not do true time-travel: Consider this example: https://godbolt.org/z/rPG14rrbj

Re: Weekend projects: getting silly with C

#50

This features the construct switch(k) { if (0) case 0: x = 1; if (0) case 1: x = 2; if (0) default: x = 3; } which is a switch where you don't have to write break at the end of every clause. #define brkcase if (0) case That might be worth using. Compilers won't love the control flow but they'll probably delete it effectively.

It only works if the case label body is a single line or is enclosed in brackets.

I'll confess, I've used this construct to mean "omit the first line of the next case label but otherwise fall through".

If you think of the case label as merely a label and not a delimiter between statements all of this makes sense.

Post reply on HN