> From: [email protected] On Behalf Of Jim Segrave
> Sent: Friday, 06 April, 2012 16:32
> On 04/06/2012 01:46 AM, Dave Thompson wrote:
> >> AES_KEY actx, dctx;
> >> printf("\n keylen = %d; kebits= %d", KEYLEN, KEYBITS);
> >>
> > Get out of the habit of outputting 'partial' lines (not
> > terminated by \n) in C. Sometimes it works and sometimes
> > it doesn't. It appears in this case on your system it didn't.
> > The standard requires complete lines to work ....
>
> I've looked through my copy of the C99 standard and the C89 standard,
> because I could not believe I'd overlooked such a caveat on printf ....
Sorry, I tailored this advice to the OP's case without
appropriately distinguishing two things.
It's not printf specifically. A C implementation may require
terminating newline on the last line of a text stream/file
(before close including normal exit), because historically
some operating systems (and filesystems) do require this.
If implementation requires it and program doesn't provide it,
behavior is undefined by omission. A sane implementor will add
a newline, or at worst drop or maybe mangle the unterminated
line, but portable code should avoid relying on it.
Also if stdout is 'determined to refer to an interactive
device' it may be unbuffered or line-buffered, in OP's case
apparently the latter. On a line-buffered stream if UB occurs
after writing a partial line and before writing the newline
that terminates it (or close/exit if permitted), the partial
line is likely to be lost, and in the OP's case this gave
a misleading impression of where the fault was. (In general
UB can be arbitrarily bad, but I say loss of buffered output
is what commonly occurs here.) And if the implementation's
determination of interactivity is mistaken, as can happen,
stdout is fully-buffered and likely to lose more.
> To the best of my knowledge there can be a restriction on the
> number of characters output in a single call to printf ....
You're probably thinking of the allowed limit on the characters
produced by a single *conversion* (C89 509, C99 4095). AFAIK
there's no limit on the output from a printf *call*, beyond the
all-purpose escape-hatch in 1 about "the size or complexity of a
program and its data that will exceed the capacity of any specific
data-processing system or the capacity of a particular processor".
Other related limits:
There can be a limit as low as C89 509 C99 4095 on characters
in a string *literal*; *printf format string often is a literal
but doesn't have to be, and other arguments sometimes are.
There can be a limit as low as C89 32767 C99 65535 bytes in
an object, and therefore that limit minus 1 characters in any
(singlebyte) string anywhere in the program, including *printf.
And of course if the stream goes to a disk file there must be
some limit on how much you can write to it by any sequence of
calls that doesn't position backwards (and possibly truncate).
Even for nondisk files there is sometimes a write limit. E.g.
TCP wraps and is theoretically infinite as long as the receiver
doesn't fall behind more than half the sequence space, but not
SSL/TLS: when it runs out of sequence numbers it must at least
renegotiate, and if it can't or doesn't it must disconnect.
Those issues aren't specific to C, of course.
> Building an output line in pieces with separate
> calls to printf to construct the pieces is a common programming
> practice. It can lead to cleaner and clearer code ....
If you ensure no UB (or other bug) in between, I agree.
So when I do this, I usually write smallish clumps of code
which collectively do complete lines, but I don't leave a
partial line 'too long' without at least trying fflush().
Like many other things, it ends up a judgement call.
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List [email protected]
Automated List Manager [email protected]