[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#616627: stdio functions should not be declared __wur (ignoring return value of ‘fwrite’, declared with attribute warn_unused_result)



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



Reply to: