4 ms·
This reminds me of some silly C code I once wrote for fun, which counts down from 10 to 1: #include <stdio.h> // compile & run: gcc -Wall countdown.c -o co
by jftuga 2y ago
This reminds me of some silly C code I once wrote for fun, which counts down from 10 to 1:
#include <stdio.h> // 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:
# run ./countdown.sh 10
echo $1 && (($1-1)) && $0 $(($1-1))
- cbrpnk 2y agoI don't think I've ever thought of explicitly calling main(). Made me chuckle.
- akdev1l 2y agoI think it is UB Edit: actually looks like it is UB in C++ but not C
- colejohnson66 2y agoWhy would calling main be UB!? How is crt0 supposed to work?
- tomjakubowski 2y agocrt0 generally isn't C and isn't subject to C's rules
- astrange 2y agomalloc() can't be implemented in C either because it's defined as doing things (creating new memory objects) there are no lower level mechanisms in C to do.
- eacnamn 2y agoall malloc is defined to do is to return a pointer to storage of appropriate size and alignment, which can easily be done in pure standard C by defining a static array and chopping it up as needed. that's not a brilliant way of doing that, but achievable without leaving standard C
- astrange 2y ago> The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate. > The lifetime of an allocated object extends from the allocation until the deallocation. Each such allocation shall yield a pointer to an object disjoint from any other object. A static array is "an object" already. A pointer to the middle of it is not a new object.
- gpderetta 2y agoAFAIK that can break because of the strict aliasing rules (although it might work in practice). Even if char can alias anything, the reverse is not true and you can't legally store other types in a static array of char type. You should be able to use anonymous memory though, so for example if you get your storeag via mmap or some other allocator it should be fine.
- astrange 2y agoThere isn't anything called mmap in the C standard. That's what I mean by it not being possible to implement in standard C. It is possible in some implementations of C.
- akdev1l 2y agoAs the other person pointed out, anything that happens before main is strictly not covered by the C standard. Even things like “printf” can’t be implemented purely in standard C. Even making a syscall is outside of the scope of the C standard.
- quietbritishjim 2y agoNitpick: 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".
- jftuga 2y agoThanks for this suggestion - it works great. import sys # run: python3 countdown.py 10 def main(n:int): print(n) or n-1 and main(n-1) main(int(sys.argv[1])) This also works and is definitely more Pythonic: _ = [print(n) for n in range(10,0,-1)]