Package: libc6-dev
Version: 2.13-0exp3
Severity: minor
Justification: noisy, results in ugly code
Tags: upstream
Forwarded: http://sourceware.org/bugzilla/show_bug.cgi?id=11959

Hi,

Testcase follows[1].

The C standard I/O facilities include an error flag on file streams,
so instead of a noisy and wasteful

        if (putchar('H') == EOF)
                handle_error();
        if (printf("el") < 0)
                handle_error();
        if (fwrite("lo", 3, 1, stdout) != 1)
                handle_error();
        if (fflush(stdout))
                handle_error();

one can write

        putchar('H');
        printf("el");
        fwrite("lo\n", 3, 1, stdout);
        fflush(stdout);
        if (ferror(stdout))
                handle_error();

POSIX does not seem to say anything about whether later I/O operations
can clobber errno after the error indicator is set so the former might
be technically more portable, but since in practice implementations do
tend to preserve errno, I see no reason to discourage the latter
practice.

Unfortunately glibc marks fwrite --- but oddly not the other stdio
output functions --- with __wur (which expands to
__attribute__((__warn_unused_result__)) when optimization is enabled
and the _FORTIFY_SOURCE feature is in use).  So to get the effect of
the latter, one has to write

        putchar('H');
        printf("el");
        if (fwrite("lo\n", 3, 1, stdout) != 1) {
                ; /* handled below. */
        }
        fflush(stdout);
        if (ferror(stdout))
                handle_error();

Even casting the return value from fwrite to (void) does not work,
presumably because the gcc developers did not want to encourage that
particular sort of ugliness.

Jim Meyering reported this upstream several months ago but upstream
has not responded.  Could you apply his patch?  Alternatively, is
there some other way to move this forward?

Thanks,
Jonathan

[1] Usage: chmod +x testcase.c; ./testcase.c

#if 0
exec gcc -O -D_FORTIFY_SOURCE "$0"
#else
#include <stdio.h>

int main(void)
{
        putchar('H');
        printf("el");
        fwrite("lo, world", sizeof("lo, world") - 1, 1, stdout);
        fputc('\n', stdout);
        if (ferror(stdout))
                perror("write");
        if (fclose(stdout))
                perror("close");
        return 0;
}
#endif



-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to