Live data from Hacker News

Bugs in Hello World

blog.sunfishcode.online

201–210 of 262 posts

Re: Bugs in Hello World

#201

Earlier quoted context omitted.

> Modern languages do catch more programmer errors than C/C++, but the more general point is that there are "edge cases" (redirecting to a file isn't an edge case) that developers need to consider that aren't magically caught, and understanding the language you use well enough so as not to write those bugs is important. But GP’s point is that modern languages can surface those issues and edge cases, and try to behave…

Indeed. One of the things you notice when writing say, Advent of Code solutions in Rust is that you're writing unwrap() a lot e.g. something like let geese = usize::from_str_radix(line.strip_prefix("and also ").unwrap().strip_suffix(" geese.").unwrap(), 10).unwrap(); All these functions, usize::from_str_radix, str::strip_prefix, str::strip_suffix are Options which could be None, and we need to decide what to do with…

> Sure enough sometimes while rushing to solve an AoC problem (...)

>In a C program taking the same approach (...)

"Writing C" and "rushing" is a strategy that cannot give you correct, robust software.

Re: Bugs in Hello World

#203

Imo this is because the responsibility is not clearly defined and can be argued upon. If my program writes to the standard output, but you choose to redirect the pipe to a different location, is it my program’s responsibility to check what happens to the bytes AFTER the pipe? After all: my program did output everything as expected . The part which fucked up was not part of my program. I can see why some projects deci…

In this scenario you didn’t write any bytes though. You made a call to write to standard out (your process’s file handle 1) and didn’t succeed, you didn’t handle the possible error condition, you just silently ignored it. I think this is pretty cut and dried - the failure is inside your process’s address space and the programmer error is that you haven’t handled a reported error. >> what happens to the bytes AFTER th…

> you didn’t handle the possible error condition, you just silently ignored it.

Problem is, the error condition is not even that obvious. I tried it, and printf() will happily return the number of bytes written, even when redirecting stdout to /dev/full.

I am not 100% sure, but I think this has to do with the fact that printf uses buffered io, and writing the bytes to the buffer will work. It's only when the buffer is flushed that this will become a problem, but this would need to be handled in the code to show an error message.

Re: Bugs in Hello World

#204
post #185

Earlier quoted context omitted.

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

hello.c is meant as the first program a new student encounters when learning C. At that point, the student has enough to worry about; writing code to a file, checking for syntactic errors, basic program structure, using the compiler, executing the binary, understanding what `#include ` means,... Sure, we could update it: // hello_v2.0.c #include #include #include int main(void) { printf("Hello, World!\n"); fflush(std…

This is much simpler:

  int n = printf("Hello, World!\n");
  return n 

Re: Bugs in Hello World

#205
post #179

Earlier quoted context omitted.

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

Most software is incapable of being incorrect, because correct behavior isn’t defined! Hence the questions here about who’s to say what’s correct. When the typical programmer says a program is “buggy” it means “it didn’t do what I want.” That’s a pleasantness property, not a correctness one.

given that the sole purpose of software is to do what people want, "it didn't do what i want" is automatically incorrect behavior

Re: Bugs in Hello World

#206
post #204

Earlier quoted context omitted.

hello.c is meant as the first program a new student encounters when learning C. At that point, the student has enough to worry about; writing code to a file, checking for syntactic errors, basic program structure, using the compiler, executing the binary, understanding what `#include ` means,... Sure, we could update it: // hello_v2.0.c #include #include #include int main(void) { printf("Hello, World!\n"); fflush(std…

This is much simpler: int n = printf("Hello, World!\n"); return n

On my machine:

    $ cat main.c
    #include 

    int main(void) {
        int n = printf("Hello, World!\n");
        return n  /dev/full
    $ echo $?
    0
Problem is, printf is buffered. When redirecting to /dev/full writing to the buffer works. The problem only manifests when the buffer is flushed.

This works, as write is not buffered;

    #include 

    int main(void) {
        int n = write(1, "Hello, World!\n", 14);
        return n 
But even then, to find out what exactly went wrong, we would have to check errno.

It's easier in Go, because fmt functions do have an error return which will report such errors;

    func main() {
        _, err := fmt.Println("Hello, World!")
        if err != nil {
            os.Exit(1)
        }
    }

Re: Bugs in Hello World

#207
post #204

Earlier quoted context omitted.

This is much simpler: int n = printf("Hello, World!\n"); return n

On my machine: $ cat main.c #include int main(void) { int n = printf("Hello, World!\n"); return n /dev/full $ echo $? 0 Problem is, printf is buffered. When redirecting to /dev/full writing to the buffer works. The problem only manifests when the buffer is flushed. This works, as write is not buffered; #include int main(void) { int n = write(1, "Hello, World!\n", 14); return n But even then, to find out what exactly…

I was expecting that printf would auto-flush at the newline, but either it doesn’t, or doesn’t report an error? An explicit fflush would probably work.

In any case, hello world examples are used for two purposes, (a) providing a simplest possible program that you can run (with an indication that it worked), and (b) to give a taste of the respective programming language. At least for the latter case, it would be useful to demonstrate the necessary error handling, if any. The above is just showing that this is not entirely trivial in C with its standard library.

Re: Bugs in Hello World

#208
post #179

Earlier quoted context omitted.

Most software is incapable of being incorrect, because correct behavior isn’t defined! Hence the questions here about who’s to say what’s correct. When the typical programmer says a program is “buggy” it means “it didn’t do what I want.” That’s a pleasantness property, not a correctness one.

given that the sole purpose of software is to do what people want, "it didn't do what i want" is automatically incorrect behavior

So that would mean as soon as your software has 2 users, it is broken because it doesn’t conform to their 2 (different) imaginary specs?

Re: Bugs in Hello World

#209
post #32

I’m disappointed. I expected some obscure edgecase (like “Main is usually a function…” [1]) but instead that’s about scope handling, contract design and responsibility shift. “Hello world” method simply calls an API to a text interface. It uses simple call, to a simple interface that is expected to be ever present. I don’t find any bug there. It won’t work if such interface isn’t available, is blocked or doesn’t exis…

I also had higher expectations after reading the title and was disappointed when I realized it was about failure to handle all possible system call results. I thought it was gonna be a bug in the C standard library or something. I still agree with the author though. This is a serious matter and it seems most of the time the vast amount of complexity that exists in seemingly simple functionality is ignored. Hello worl…

Userspace should not expect that any given syscall can only return some set of known errno values. You should enumerate the cases where you want to do some kind of special handling (with EINTR being somewhat more important that other cases) and have path to somehow handle even unexpected errno values.

Both Linux man pages and SUS specify some set of possible error situations, but not all of them. In the man pages case the set is not at all fixed and is subject to change and often does not contain some of the more obscure error states. The SUS "Errors" section are explicitly not meant to be complete and the OS can return additional errno values, additionally the OS can even handle some of the error cases as undefined behavior and not return any error code at all (notable example: doing anything to already joined pthread_t on linux, whish is undefined and does not return -ESRCH).

Re: Bugs in Hello World

#210
post #209

Earlier quoted context omitted.

I also had higher expectations after reading the title and was disappointed when I realized it was about failure to handle all possible system call results. I thought it was gonna be a bug in the C standard library or something. I still agree with the author though. This is a serious matter and it seems most of the time the vast amount of complexity that exists in seemingly simple functionality is ignored. Hello worl…

Userspace should not expect that any given syscall can only return some set of known errno values. You should enumerate the cases where you want to do some kind of special handling (with EINTR being somewhat more important that other cases) and have path to somehow handle even unexpected errno values. Both Linux man pages and SUS specify some set of possible error situations, but not all of them. In the man pages cas…

You're right. The manual contains this ominous notice at the very end of the errors section:

https://man7.org/linux/man-pages/man2/write.2.html

> Other errors may occur, depending on the object connected to fd.

I don't understand why every possible result isn't explicitly documented. This is the Linux system call interface, we need to know everything that could happen when we make these calls.

Post reply on HN