The bc utility is implemented historically as a front-end
processor for dc; dc was not selected to be part of this volume
of POSIX.1‐2017 because bc was thought to have a more intuitive
programmatic interface. Current implementations that implement bc
using dc are expected to be compliant.
The exit status for error conditions has been left unspecified
for several reasons:
* The bc utility is used in both interactive and non-
interactive situations. Different exit codes may be
appropriate for the two uses.
* It is unclear when a non-zero exit should be given; divide-
by-zero, undefined functions, and syntax errors are all
possibilities.
* It is not clear what utility the exit status has.
* In the 4.3 BSD, System V, and Ninth Edition implementations,
bc works in conjunction with dc. The dc utility is the
parent, bc is the child. This was done to cleanly terminate
bc if dc aborted.
The decision to have bc exit upon encountering an inaccessible
input file is based on the belief that bc file1 file2 is used
most often when at least file1 contains data/function
declarations/initializations. Having bc continue with
prerequisite files missing is probably not useful. There is no
implication in the CONSEQUENCES OF ERRORS section that bc must
check all its files for accessibility before opening any of them.
There was considerable debate on the appropriateness of the
language accepted by bc. Several reviewers preferred to see
either a pure subset of the C language or some changes to make
the language more compatible with C. While the bc language has
some obvious similarities to C, it has never claimed to be
compatible with any version of C. An interpreter for a subset of
C might be a very worthwhile utility, and it could potentially
make bc obsolete. However, no such utility is known in historical
practice, and it was not within the scope of this volume of
POSIX.1‐2017 to define such a language and utility. If and when
they are defined, it may be appropriate to include them in a
future version of this standard. This left the following
alternatives:
1. Exclude any calculator language from this volume of
POSIX.1‐2017.
The consensus of the standard developers was that a simple
programmatic calculator language is very useful for both
applications and interactive users. The only arguments for
excluding any calculator were that it would become obsolete
if and when a C-compatible one emerged, or that the absence
would encourage the development of such a C-compatible one.
These arguments did not sufficiently address the needs of
current application developers.
2. Standardize the historical dc, possibly with minor
modifications.
The consensus of the standard developers was that dc is a
fundamentally less usable language and that that would be far
too severe a penalty for avoiding the issue of being similar
to but incompatible with C.
3. Standardize the historical bc, possibly with minor
modifications.
This was the approach taken. Most of the proponents of
changing the language would not have been satisfied until
most or all of the incompatibilities with C were resolved.
Since most of the changes considered most desirable would
break historical applications and require significant
modification to historical implementations, almost no
modifications were made. The one significant modification
that was made was the replacement of the historical bc
assignment operators "=+"
, and so on, with the more modern
"+="
, and so on. The older versions are considered to be
fundamentally flawed because of the lexical ambiguity in uses
like a=-1.
In order to permit implementations to deal with backwards-
compatibility as they see fit, the behavior of this one
ambiguous construct was made undefined. (At least three
implementations have been known to support this change
already, so the degree of change involved should not be
great.)
The '%'
operator is the mathematical remainder operator when
scale
is zero. The behavior of this operator for other values of
scale
is from historical implementations of bc, and has been
maintained for the sake of historical applications despite its
non-intuitive nature.
Historical implementations permit setting ibase
and obase
to a
broader range of values. This includes values less than 2, which
were not seen as sufficiently useful to standardize. These
implementations do not interpret input properly for values of
ibase
that are greater than 16. This is because numeric constants
are recognized syntactically, rather than lexically, as described
in this volume of POSIX.1‐2017. They are built from lexical
tokens of single hexadecimal digits and <period> characters.
Since <blank> characters between tokens are not visible at the
syntactic level, it is not possible to recognize the multi-digit
``digits'' used in the higher bases properly. The ability to
recognize input in these bases was not considered useful enough
to require modifying these implementations. Note that the
recognition of numeric constants at the syntactic level is not a
problem with conformance to this volume of POSIX.1‐2017, as it
does not impact the behavior of conforming applications (and
correct bc programs). Historical implementations also accept
input with all of the digits '0'
-'9'
and 'A'
-'F'
regardless of
the value of ibase
; since digits with value greater than or equal
to ibase
are not really appropriate, the behavior when they
appear is undefined, except for the common case of:
ibase=8;
/* Process in octal base. */
...
ibase=A
/* Restore decimal base. */
In some historical implementations, if the expression to be
written is an uninitialized array element, a leading <space>
and/or up to four leading 0 characters may be output before the
character zero. This behavior is considered a bug; it is unlikely
that any currently conforming application relies on:
echo 'b[3]' | bc
returning 00000 rather than 0.
Exact calculation of the number of fractional digits to output
for a given value in a base other than 10 can be computationally
expensive. Historical implementations use a faster
approximation, and this is permitted. Note that the requirements
apply only to values of obase
that this volume of POSIX.1‐2017
requires implementations to support (in particular, not to 1, 0,
or negative bases, if an implementation supports them as an
extension).
Historical implementations of bc did not allow array parameters
to be passed as the last parameter to a function. New
implementations are encouraged to remove this restriction even
though it is not required by the grammar.