Live data from Hacker News

Bugs in Hello World

blog.sunfishcode.online

181–190 of 262 posts

Re: Bugs in Hello World

#181

> There's our "No space" error getting reported by the OS, but no matter, the program silently swallows it and returns 0, the code for success. That's a bug! Bzzt, no. You can't say that without knowing what the program's requirements are. Blindly "fixing" a program to indicate failure due to not being able to write to standard output could break something. Maybe the output is just a diagnostic that's not important,…

> if something is picking up the output and parsing it as JSON, it can deduce from a failed parse that the program didn't complete, rather than going by termination status.

This is bad advice. Consider output that might be truncated but can't be detected (mentioned in the article).

The exit status is the only reliable way to detect failures (unless you have a separate communication channel and send a final success message).

Re: Bugs in Hello World

#182
post #55
post #45

Earlier quoted context omitted.

The bug is not that the program failed, it's that the program failed but reported a success.

I think they are arguing that it didn’t fail, it did everything you asked of it (it didn’t claim to successfully print hello world in every scenario, just to attempt to write to the buffer you gave it, which it did).

Well, if you want your hello world program to try to write Hello world, then report success regardless of the result, then it is bug-free. If you intend your program to write hello world on your screen/stdout, then it is definitely buggy.

The computer will do what you ask it to do, it's only a bug, when it doesn't meet your expectations.

Re: Bugs in Hello World

#183

Enjoyable read for sure, but i think the question whether ot not this constitutes a bug or not is open for interpretation. IMHO, it doesn't. hello.c is written in a way that makes it very clear that the program doesn't care about error conditions in any way shape or form; the return value of printf is ignored, the output isn't flushed, the return of flushing isn't checked, noone looks at errno; ...so anything happeni…

>If I expect a program to do something (eg. handle IO errors) that its code says very clearly that it doesn't, that's not the programs fault.

Is there no such thing as a bug then? The program does what the code says so every "misbehavior" and crash is expected behavior.

Re: Bugs in Hello World

#184

> There's our "No space" error getting reported by the OS, but no matter, the program silently swallows it and returns 0, the code for success. That's a bug! Bzzt, no. You can't say that without knowing what the program's requirements are. Blindly "fixing" a program to indicate failure due to not being able to write to standard output could break something. Maybe the output is just a diagnostic that's not important,…

There is more nuance to this, which is that we cannot detect all modes of failure just because we have written to a file object, and successfully flushed and closed it.

In the case of file I/O, we do not know that the bits have actually gone to the storage device. A military-grade hello world has to perform a fsync. I think that also requires the right storage hardware to be entirely reliable.

If stdout happens to be a TCP socket, then all we know from a successful flush and close is that the data has gone into the network stack, not that the other side has received it. We need an end-to-end application level ack. (Even just a two-way orderly shutdown: after writing hello, half-close the socket. Then read from it until EOF. If the read fails, the connection was broken and it cannot be assumed that the hello had been received.)

This issue is just a facet of a more general problem: if the goal of the hello world program is to communicate its message to some destination, the only way to be sure is to obtain an acknowledgement from that destination: communication must be validated end-to-end, in other words. If you rely on any success signal of an intermediate agent, you don't have end-to-end validation of success.

The super-robust requirements for hello world therefore call for a protocol: something like this:

    puts("Hello, world!");
    puts("message received OK? [y/n]")
    return (fgets(buffer, sizeof buffer, stdin) != NULL && buffer[0] == 'y')
            ? EXIT_SUCCESS : EXIT_FAILURE;
Now we can detect failures like that there is no user present at the console who is reading the message. Or that their monitor isn't working so the can't read the question.

We can now correctly detect this case of not being able to deliver hello, world, converting it to a failed status:

  $ ./hello  /dev/null
We can still be lied to, but there is strong justification in regarding that as not our problem:

  $ yes | ./hello > /dev/null
We cannot get away from requiring syntax, because the presence of a protocol gives rise to it; the destination has to be able to tell somehow when it has received all of the data, so it can acknowledge it.

A super reliable hello world also must not take data integrity for granted; the message should include some kind of checksum to reduce the likelihood of corrupt communication going undetected.

Re: Bugs in Hello World

#185

Enjoyable read for sure, but i think the question whether ot not this constitutes a bug or not is open for interpretation. IMHO, it doesn't. hello.c is written in a way that makes it very clear that the program doesn't care about error conditions in any way shape or form; the return value of printf is ignored, the output isn't flushed, the return of flushing isn't checked, noone looks at errno; ...so anything happeni…

For didactic reasons it’s preferable to consider it a bug.

Re: Bugs in Hello World

#186

Earlier quoted context omitted.

> some other people disagree and say you should never use `set -e` outside of development I'm really interested. What are their arguments? And how do they handle errors?

See https://mywiki.wooledge.org/BashFAQ/105 for examples of side effects. I think the idea is you use set -e during development to find where you should catch errors, but in production you may want it off to reduce strange side-effects (or explicitly check for success in the way you expect; so not that the command returned 0 but that the file it made exists and is the right length, etc).

> not that the command returned 0 but that the file it made exists and is the right length

If a command returns 0 when it didn't really do its job. Shouldn't we fix the command instead of the script?

Re: Bugs in Hello World

#187

Enjoyable read for sure, but i think the question whether ot not this constitutes a bug or not is open for interpretation. IMHO, it doesn't. hello.c is written in a way that makes it very clear that the program doesn't care about error conditions in any way shape or form; the return value of printf is ignored, the output isn't flushed, the return of flushing isn't checked, noone looks at errno; ...so anything happeni…

This is a strange definition of 'buggy' to me. Surely it shouldn't depend on anything to do with the source code, otherwise closed-source programs are all 'neither-buggy-nor-not-buggy' and that can't be the case...

[deleted]

Re: Bugs in Hello World

#188
post #159

Earlier quoted context omitted.

> a hyperbole It's not, though. This helloworld is not safe to use as part of something bigger. Like: echo header > gen.txt && ./helloworld >> gen.txt && ./upload_to_prod gen.txt That will upload a partial file to prod, if there's any write error. > It's not meant to be part of a shell script You don't know that. And brittle pieces like this is absolutely not an uncommon source of bugs.

If you don't know how the program is going to be used, how do you know that it is doing the right thing? Is "Hello world" actually the expected output? Also, what makes the status code handling special compared to, say, - assuming the english language is the preferred language instead of asking the OS for the user's preference - assuming that the output has to be ASCII (or compatible) instead of something like UTF-16…

> Is "Hello world" actually the expected output?

Isn't that the definition of helloworld?

> Also, what makes the status code handling special compared to, say, - assuming the english language is the preferred language instead of asking the OS for the user's preference - assuming that the output has to be ASCII (or compatible) instead of something like UTF-16

True. But by any definition printing nothing is a failure. If failing to print anything isn't a failure, what is?

> There seems to be a weird obsession with the program's status code over anything else in this whole comment section

It's because it's the only structured way to indicate success. And "not printing" is clearly a failure of "print 'hello world'".

> supporting the latter is hard and therefore assumed to be less important.

No, but printing nothing is clearly a failure. Printing the wrong language is not obviously a failure of helloworld, and absolutely not something helloworld can know on its own.

helloworld can know it failed to print what it intended to print. It cannot confirm that its intentions are correct, even in principle.

It cannot know whether some Lennartware has decided that anything built before yesterday (e.g. LANG envs and friends) can be ignored, and that in Lennart land all programs should write a request for the language to the blockchain, and wait for a reply transaction before printing anything.

Just because you can come up with examples of errors helloworld cannot check, doesn't mean that it should not do error handling for the things that it can.

`tar` cannot check that the user actually intended the particular file format flavor that it implements, but it can know that failing to write it should cause it to report an error.

Re: Bugs in Hello World

#189
post #17

It's a fun take, but a hyperbole nonetheless. hello.c is supposed to be run from a terminal and write back to it: there's always space to write. It's not meant to be part of a shell script, so the error status is irrelevant. It does show that we take such examples a bit too literally: our feeble minds don't consider what's missing, until it's too late. That's a didactic problem. It only matters to certain kinds of so…

> a hyperbole It's not, though. This helloworld is not safe to use as part of something bigger. Like: echo header > gen.txt && ./helloworld >> gen.txt && ./upload_to_prod gen.txt That will upload a partial file to prod, if there's any write error. > It's not meant to be part of a shell script You don't know that. And brittle pieces like this is absolutely not an uncommon source of bugs.

> You don't know that

The first piece of C code in introduction section was meant as production software? I've checked it: that section mentions typing "a.out" in the the UNIX shell to see what happens.

Re: Bugs in Hello World

#190

> There's our "No space" error getting reported by the OS, but no matter, the program silently swallows it and returns 0, the code for success. That's a bug! Bzzt, no. You can't say that without knowing what the program's requirements are. Blindly "fixing" a program to indicate failure due to not being able to write to standard output could break something. Maybe the output is just a diagnostic that's not important,…

> if something is picking up the output and parsing it as JSON, it can deduce from a failed parse that the program didn't complete, rather than going by termination status. This is bad advice. Consider output that might be truncated but can't be detected (mentioned in the article). The exit status is the only reliable way to detect failures (unless you have a separate communication channel and send a final success me…

My remark "if a program produces output with a well-defined syntax" was intended specifically to consider such cases, and set them aside.

I didn't communicate that clearly: syntax can be "well-defined" yet truncatable. I meant some kind of syntax that is invalid if any suffix is missing, including the entire message, or else an object of an unexpected type is produced.

(In the case of JSON, valid JSON could be output which is truncatable, like 3.14 versus 3.14159. If the output is documented and expected to be a dictionary, we declare failure if a number emerges.)

Post reply on HN