> From: owner-openssl-us...@openssl.org 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                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to