> 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