Hacker News new | past | comments | ask | show | jobs | submit login

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))



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".


Thanks 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)]


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


I think it is UB

Edit: actually looks like it is UB in C++ but not C


Why would calling main be UB!? How is crt0 supposed to work?


crt0 generally isn't C and isn't subject to C's rules


malloc() 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.


all 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


AFAIK 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.


There 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.


> 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.


As 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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: