Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
Oh, actually I indeed thought that printing a constant string would not
create any error that would then be indicated by printf's return value.
Linux has a device called "/dev/full". It acts like it has no data
on input, and like it's full on output. You can redirect a program's
stdout to /dev/full. It's useful for testing, and much easier than
finding a writable filesystem with no remaining space. (/dev/null
accepts and discards as much intput as you send to it.)
[...]
I'd indeed also expected that, say, printing a string value with a '%d'
specifier would produce an error, but I saw that it doesn't; while the
compiler creates just a warning, execution provides some random output
and a _non-negative_ string-length value as printf's return value. Not
exactly what I'd expect from a language.
Calling printf with a mismatch between the format string and
an argument has undefined behavior. Some compilers will warn
about this in most cases, but in general the format string is not
necessarily known at compile time.
No diagnostic or other error indication is required.
[...]
Obviously (because of that?) I've never seen anyone test such a call
by, say,
int rc = printf("Hello, world\n");
if (rc < 0) {
/* umm.. */
}
Quick-and-dirty programs like the classic "hello, world" often don't
bother to check. The above could print an error message to stderr and
call exit(EXIT_FAILURE). Even if stdout and stderr both produce errors,
the caller should be able to detect the error status. (I've configured
my shell to print a message when a program dies with an error status.)
But most production programs don't just blindly print stuff to stdout.
[...]
Are you - plural, all CLC audience - writing such code with 'printf()',
honestly? - Same question with 'int rc = fclose (...);' - what can one
do about that, then? (Write a logfile entry, maybe? - and then?)
Write the error message to stderr, optionally log it somewhere,
and exit with an error code.
On 2026-06-11 18:37, Janis Papanagnou wrote:[...]
I'd indeed also expected that, say, printing a string value with a '%d'
specifier would produce an error, but I saw that it doesn't; while the
compiler creates just a warning, execution provides some random output
and a _non-negative_ string-length value as printf's return value. Not
exactly what I'd expect from a language.
On some systems I've used, it would try to interpret the pointer to the string as an int, and print the result.
On others, it would expect the
int to be stored in one register, whereas the pointer was stored in a different register, and as a result it would print whatever value was
last stored in the first register. These were natural outcomes for those implementations; had the C standard imposed any conflicting requirements
on the behavior, it would have complicated those implementations.
[...]
Obviously (because of that?) I've never seen anyone test such a call
by, say,
int rc = printf("Hello, world\n");
if (rc < 0) {
/* umm.. */
}
Are you - plural, all CLC audience - writing such code with 'printf()',
honestly? - Same question with 'int rc = fclose (...);' - what can one
do about that, then? (Write a logfile entry, maybe? - and then?)
For most of the programs I ever wrote, a single check for ferror(file)
at the end of the program, resulting in exit(EXIT_FAILURE) being called, would be acceptable.
That approach relies on the fact that the error
flag is sticky. Because I made a habit of such checks, we caught a
problem when a disk overflowed before we'd wasted hours "writing" data
to nowhere. If I had sent a message to a log file, it would have been
blocked by the same problem, which is why I used the exit status to
report the problem.
[...]
On 2026-06-12 02:41, Keith Thompson wrote:[...]
Calling printf with a mismatch between the format string and
an argument has undefined behavior. Some compilers will warn
about this in most cases, but in general the format string is not
necessarily known at compile time.
Well, yes. But therefore I imagined that at runtime an rc<0 could have indicated such a mismatch.
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 2026-06-12 02:41, Keith Thompson wrote:
[...]
Calling printf with a mismatch between the format string and an
argument has undefined behavior. Some compilers will warn about
this in most cases, but in general the format string is not
necessarily known at compile time.
Well, yes. But therefore I imagined that at runtime an rc<0
could have indicated such a mismatch.
That would be nice, but it's just one of the infinitely many
possible results of undefined behavior.
For example, this program:
#include <stdio.h>
int main(void) {
const int result = printf("%ld\n", 0.3);
printf("printf returned %d\n", result);
}
on my system prints:
140732048673560
printf returned 16
gcc and clang warn about the format string. tcc doesn't.
The (first) printf call was apparently successful because printf
has no way to know that the argument was of an incorrect type
(types don't really exist at run time).
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:[...]
For example, this program:
#include <stdio.h>
int main(void) {
const int result = printf("%ld\n", 0.3);
printf("printf returned %d\n", result);
}
on my system prints:
140732048673560
printf returned 16
gcc and clang warn about the format string. tcc doesn't.
The (first) printf call was apparently successful because printf
has no way to know that the argument was of an incorrect type
(types don't really exist at run time).
printf() could know if an argument were of an incorrect type, if
an implementation chose to do so.
| Sysop: | Tetrazocine |
|---|---|
| Location: | Melbourne, VIC, Australia |
| Users: | 12 |
| Nodes: | 8 (0 / 8) |
| Uptime: | 201:54:45 |
| Calls: | 220 |
| Files: | 21,513 |
| Messages: | 83,435 |