Subject: SC 22 N 3470 - Summary of Voting on SC 22 N 3395, Letter Ballot f or ISO/IEC PDTR 18037 - C Extensions to Support Embedded

From: Matthew Deane <[email-masked]>
Date: Thu, 15 Aug 2002 12:12:25 -0400

ISO/IEC JTC 1/SC22
Programming languages, their environments and system software interfaces
Secretariat:  U.S.A.  (ANSI)
 
ISO/IEC JTC 1/SC22 N3470
 
TITLE:
Summary of Voting on SC 22 N 3395, Letter Ballot for ISO/IEC PDTR 18037 - C
Extensions to Support Embedded
Processors

DATE ASSIGNED:
2002-08-15
 
SOURCE:
SC 22 Secretariat

BACKWARD POINTER:
N/A
 
DOCUMENT TYPE:
Summary of Voting

PROJECT NUMBER:
22.18037
 
STATUS:
The results of this ballot are forwarded to SC 22/WG 14 for review,
production of a disposition of comments report, and preparation of the DTR
text.

ACTION IDENTIFIER:
ACT
 
DUE DATE:
  
DISTRIBUTION:
Text

CROSS REFERENCE:
SC 22 N3395

DISTRIBUTION FORM:
Def
 
Address reply to:
ISO/IEC JTC 1/SC22 Secretariat
Matt Deane
ANSI
25 West 43rd Street
New York, NY  10036
Telephone:  (212) 642-4992
Fax:             (212) 840-2298
Email:  [email-masked]

_______end of cover page, beginning of summary____________

SUMMARY OF VOTING ON

Letter Ballot Reference No:  SC22 N3395
Circulated by:               JTC 1/SC22
Circulation Date:            2002-05-03
Closing Date:                2002-08-05

SUBJECT:  Summary of Voting on SC 22 N 3395, Letter Ballot for ISO/IEC PDTR
18037 - C Extensions to Support Embedded
Processors
----------------------------------------------------------------------

The following responses have been received on the subject of approval:

"P" Members supporting approval without comment                   

8 (Canada, China, Czech Republic, Denmark, Finland, Republic of Korea,
Norway, Ukraine)

"P" Members supporting approval with comments              

3 (Germany, Netherlands, USA)        

"P" Members not supporting approval       

1 (UK)

"P" Members abstaining                    

1 (Switzerland)

"P" Members not voting                    

10 (Austria, Belgium, Brazil, Egypt, Ireland, Japan, DPR of Korea, Romania,
Russian Federation, Slovenia)

Note:  O-member Italy voted to approve without comments.

___________ end of summary, beginning on NB comments _____________

Germany
The concept for fixed-point arithmetic is tailored to digital signal
processing. An extension to support a greater number of fixed-point types
may pose some difficulties. Other application areas might require decimal
fixed-point numbers (as opposed to binary fixed-point numbers) and a
different handling of overflow and rounding.

Netherlands
The Netherlands approves the document with the following remarks.
None of the points mentioned are considered to be critical at this
point in time.

  1.  Section 2.1.4 does not define what the result is when an
      integer type is combined with a fixed-point type and one of
      the types is signed and the other is unsigned (e.g.,
      signed fract * unsigned int).
      We assume that this also yields a signed result.

  2.  The operation 'int + fract' (or 'int - fract') is for almost
      all values of the int operand a useless (and possibly
      erroneous) operation.  The Rationale should make clear why
      this combination is still allowed (should an implementation
      be encouraged to flag these operations?).

  3.  Add library functions for 'int * fract -> int'.  Rounding
      towards zero?

  4.  Add library functions for 'int / fract -> int'.  Rounding
      towards zero?

  5.  The last paragraph of section 6.5 of the C standard
      introduces the concept of a `contracted expression' that
      allows implementations to enhance the speed of the
      implementation while sacrificing predictability, and perhaps
      (almost as a side-effect?)  increasing accuracy (see also
      note 75).
      A fixed-point example where a similar approach might be
      applied is:
            long fract = long fract + fract * fract
      The current specification requires the fract * fract part to
      be rounded to fract before the addition is done, thereby
      loosing precision and (often) requiring additional
      instructions.  A similar case is
            fract = fract1 * fract2 * fract3
      where also intermediate rounding takes place.
      It should be investigated whether the floating-point
      `contracted expression' approach can be extended to include
      fixed-point arithmetic.  If this is done, warnings similar to
      those in note 75 of the C standard should be repeated in the
      fixed-point context.

  6.  It is felt that the penultimate paragraph of 2.1.6.1, dealing
      with the special treatment of the values 1 and -1 as
      resultvalues of a multiplication operation, is too special
      and confusing.  For instance: why also include the value -1
      here which can always be represented?  And what happens with
      this `saturating' behaviour when the state of the FX_OVERFLOW
      switch is MODWRAP?
      It is proposed to remove this special treatment.

  7.  The reasons to include unsigned fixed-point arithmetic in the
      document (orthogonality, analogy to integer arithmetic, some
      processors support it) are fully endorsed.  Still, it is
      realized that the feature does add to the complexity of the
      specification (doubles the amount of types, requires special
      treatment etc).
      It might be useful to include more justification.  Is there a
      striking example (hardware or application) that benefits from
      unsigned fixed-point arithmetic that can be described?

  8.  The need for and the usage of the FX_OVERFLOW state DEFAULT
      is not clearly described.  Maybe DONTCARE is a better name
      for this state, as it is intended to be used for those pieces
      of code for which overflowhandling is not critical.

  9.  The current text in section 3.2.1 allows address-space-
      qualifiers to be used for struct- and union-members; this
      should be disallowed.

 10.  The current text in section 3.2.1 allows address-space-
      qualifiers to be used in function prototypes and function
      declarations; is that the intention, or should it be
      disallowed?

 11.  Section 3.2.2 (Processor register access) introduces a
      concept of register variables with file scope.  This is
      highly irregular and errorprone.
      It is proposed to either move the description of this
      functionality from the main body to the annex, or,
      preferably, to remove the functionality completely.

 12.  It should be an error when an address-space-qualifier is used
      in conjunction with a register declaration (section 3.2.5.1).

United Kingdom
Acceptance of these reasons and appropriate changes in the text will change
our vote to approval 
----------------------------------------------------------------------------
---------
Report from IST/5 UK National Body The material in this technical report
addresses specialised problems in niche environments. To require support for
these features from all compiler vendors would impose unwarranted hardship
on members of the broader community. In the front matter a disclaimer should
be added that there is no intention of incorporating this material into a
future revision of the C standard. If incorporation were proposed today in
the current form, the UK would vote NO. 
<---------------------------------------------------------------------------
-------->
There are technical defects in the proposed TR, but so long as they never
become part of the C Standard the damage they can do should remain minimal.
These are our other comments:
<---------------------------------------------------------------------------
-------->
p. 11, 2.1.5: The mechanism of using suffixes to denote the type of literals
is not scalable. This affects not just fixed-point data types but also
character literals and format specifiers. A better mechanism should be
devised for some future revision of the C standard. This is an opportunity
for the C and C++ committees to collaborate on a common solution to a common
problem. 
p. 11, 2.1.5: Using 'q' as a suffix for _Accum literals conflicts with
existing practice for designating "quad" floating point numbers on Itanium
processors.
p. 9, 2.1.3: Fixed-point overflow has undefined behaviour by default.
Undefined behaviour is evil. The default overflow behaviour should be
implementation-defined. 
p. 32, 7.18.6.2: When rounding, "If the value of n is negative or larger
than the
number of fractional bits in the fixed-point type of f, the result is
undefined." An "undefined result" is not a defined term; it should say the
result is unspecified.
p.64, B.1.2: (#pragma addressmod) The grammar of the language does not allow
preprocessor directives to extend over more than one logical line. Each
physical line should end with a '\' character. The ',' following
"Write_access" should be moved inside the square brackets (assuming it is
optional). The trailing ';' is unconventional and doesn't appear to add any
meaning.
p. 42, 3.2.3.3: If memory-space-modified pointers are restricted to
referencing that address space, what should happen if an alien address is
assigned to them? Compiler diagnostic? Seg fault? Undefined behaviour? The
document should specify the behaviour in this case.
p. 42, 3.2.4: If memory-space-modified pointers are restricted to
referencing that address space, then a pointer to nested memory space A
should NOT be used to point to objects in enclosing named address space B.
Remove the "implementation dependent" possibility of doing so from the
document.
p. 42, 3.2.3.3: Is it necessary to use some kind of memory-space-cast to
assign a value from an unmodified pointer (which can address any memory
space) to one which is restricted to the named space? What syntax should
this take? Note that 3.2.6 refers to an "implied cast to an unmodified
pointer". Do such conversions need to be spelled out in connection with the
Standard's paragraphs on casts, conversions, promotions, etc? Pointers to
different address spaces are allowed to be different sizes (3.2.4). Can a
memory-space-modified pointer be a function pointer?
p. 43, 3.2.5.1 s/that are do need to have/that do not need to have/
p. 43, 3.2.5.3 "int myspace[10]; /* not allowed */" 
-- presumably should be something like: "int myspace arr[10];" ?
But this raises the question, what is the scope of named address space
identifiers? Can they be hidden by declarations in a nested scope, like
other identifiers? This should be explained in the document.
p. 43, 3.2.6 "Code will then port between different target platforms." This
sounds a bit vague (not to mention pie-in-the-sky). Source code or
executable code? Does "different target platforms" refer to different
compilers targeting the same processor or embedded system? Or does it mean
different processor systems, which may happen
to have the same kinds of memory space but arrange them differently?
(Some embedded systems have RAM and ROM on a single chip, others use a
combination of chips.) Clarify.
p.64, B.1.2, and p. 74, D.2: There seems to be some overlap between the
address spaces proposal and the hardware i/o proposal, at least as relates
to specifying the base address and the register width. If there is
duplication or conflict, these should be harmonised.
<---------------------------------------------------------------------------
-------->

United States
Comments:
__X__  general:
2.1.5 Fixed-point constants
The suffixes 'q' and 'Q' are already in use by several implementers
for quad precision floating-point.  Need to find a different suffix.

2.1.6.2.1	Binary arithmetic operators

What is the result of fixed-point type operator floating-point type?
Rationale implies it is floating-point type.

2.1.7 Fixed-point functions
The suffix 'q' is already in use by several implementers for quad
precision floating-point.  Need to find a different suffix.

Section 6.4.4.3 Fixed-point constants
The suffixes 'q' and 'Q' are already in use by several implementers for quad
precision floating-point.  Need to find a different suffix.
7.18 Fixed-point arithmetic
The suffix 'q' is already in use by several implementers for quad
precision floating-point functions.  Need to find a different suffix.

7.18.6.3 The fixed-point countls functions
If the argument is zero, the result should be just N-1 (not at least N-1).
3.2.5.1 Register storage class
'that are do need' needs to be reworded.
F.1	Circular buffers

'in various processor is so divers' needs to be reworded.
Perhaps 'divers' should be 'diverse'?

* We are very uncomfortable with pragmas being used to define
identifiers as proposed in Annex B for address space qualifiers and
in Annex D for "access_spec"s.  *BDTI expects it would feel obliged
to vote against the final document if it contains such pragmas.*

* A topic currently overlooked by the technical report is the need
to define and create objects (usually arrays) with more restrictive
alignments in memory than the default.  For the best efficiency
it would not be unusual, for example, to require that an array
of 16-bit "fract"s begin on a 16- or 32-byte boundary.  Often
these requirements arise for reasons unknown to the compiler, so
the compiler cannot always be counted on to ensure the necessary
alignments automatically.  Two new features would address this
concern:  Variants of "malloc" and "realloc" that take an additional
alignment parameter for objects allocated on the heap, and a new
standard pragma for objects not allocated on the heap.

__X__  technical:
Section 2, Fixed-point arithmetic:
* It would be more convenient if the "FX_OVERFLOW" pragma were
split into two versions, one controlling "fract" overflows
("FX_FRACT_OVERFLOW"), and the other controlling "accum" overflows
("FX_ACCUM_OVERFLOW").  It is not unusual to need "fract" operations
to saturate and at the same time to know that "accum" operations
will never overflow.  If turning on saturation costs overhead on
a machine, it would be better to pay that overhead only for the
"fract" operations that might overflow and not for the "accum"
operations.  Currently, making this distinction requires turning
"FX_OVERFLOW" on and off between "fract" and "accum" operations, or,
alternatively, forgoing the pragma and fastidiously using the "sat"
keyword with "fract" operations but not "accum" ones.  (The way
"sat" is propagated through operations doesn't always make this
completely trivial, either.)

* The committee should consider whether there aren't too many fixed-
point types.  Two options for reducing the number of types:
* Eliminate the overflow qualifiers "sat" and "modwrap".  They
add complexity to the type system and would probably not
be more convenient than the two pragmas "FX_FRACT_OVERFLOW"
and "FX_ACCUM_OVERFLOW", assuming both were provided.  (BDTI
originally favored the overflow qualifiers, but that was before
pragmas were part of the proposal.)

* Eliminate all the unsigned fixed-point types except "unsigned
short fract" and "unsigned short accum".  As far as we know, no
one has claimed a need for the larger unsigned types, other than a
kind of "inertia of consistency".

Among other benefits, a reduction in the number of types would
dramatically cut the number of identifiers that must be defined by a
C++-compatibility header (Annex G).

* The following natural operations are not directly supported:

integer * fract -> integer
integer / integer -> fract
integer / fract -> integer
fract / fract -> integer

Functions or macros should be supplied for these operations
(although probably not for all possible combinations of types).

* The "fract" functions "abshr", "absr", "abslr", "roundhr", "roundr",
"roundlr", "rounduhr", "roundur", and "roundulr" (2.1.7.1 and
2.1.7.2) should be defined to return a saturated result if the true
result cannot be represented; otherwise, the functions won't be
useful in many situations.

* A type-generic "fxbits" function (2.1.7.6) isn't possible, because
the specific function to be substituted is not uniquely determined
by the type of the operand.  While the complement type-generic
"bitsfx" function is feasible, neither "bitsfx" or "fxbits" is
really needed, so the simplest course is to drop both.

In Section 2.2 on specific changes:
* The sentence

If an argument has fixed-point type, the behavior is undefined.
should not be added to Section 6.5.2.2.  It should be possible to
call non-prototyped functions with fixed-point arguments just as for
other types.

Section 3, Multiple address spaces support:
* The keywords "const", "volatile", "restrict", and "register" should have
their usual meanings when mixed with address space qualifiers (3.1.3 and
3.2.5.1).
* Address space qualifiers for registers are problematic (3.2.2);
for example, on most systems it won't be possible to have a pointer
into any of these pseudo-address-spaces.  Section 3.2.2 doesn't add
anything to the technical report and should be dropped.

* A cleaner, more general model is needed for the nesting of address
spaces (3.2.4) and for pointers into address spaces (3.2.3.3 and
elsewhere).  We would suggest something along the lines of the
following model (but not this specific text):

   --------------------------------------------------------------------
Every object exists in some address space (and possibly in multiple
address spaces, if address spaces overlap).  If the type of an
object includes an address space qualifier, the object exists in
the specified address space; otherwise, the object exists in the
_generic_ address space.  An implementation must support the generic
address space (of course), and may support other, named address
spaces.  For any two address spaces, either the address spaces
are disjoint, they are the same, or one is a subset of the other.
Other forms of overlapping are not allowed.  The implementation must
define the relationship between all pairs of address spaces.  (There
is no requirement that all named address spaces be subsets of the
generic address space.)

As determined by its type, every pointer points into a specific
address space, either the generic address space or a named address
space.  A pointer into an address space can only point to objects
in that address space (including subset address spaces).  A pointer
into address space A can be cast to a pointer into address space B,
but such a cast is undefined if the source pointer does not point to
an object in B.  (If A is a subset of B, the cast is always valid;
if B is a subset of A, the cast is valid only if the source pointer
points to an object in B.)  A constraint requires that if a pointer
into address space A is assigned to a pointer into address space B,
then A must be a subset of B.  (This constraint can be avoided with
a cast.)
   --------------------------------------------------------------------

Section 4, Basic I/O hardware addressing
* The introduction to Section 4.3 says that

An implementation is allowed to implement the interface by use
of inline functions, intrinsic functions, or intrinsic function
overloading, and still be conforming, as long as the interface
seen from the user source remain the same.

But "iord" cannot be implemented as an inline function if it is
really supposed to return different types depending on the register
size, because then the function has no specific return type.  A
similar issue applies to the argument type of "iowr", etc., unless
the inline function is defined to have an argument type larger
than any possible register type.  The C Standard does not define
"intrinsic function" or "intrinsic function overloading", and we
do not know for sure what these mean (or how they could be anything
other than the same thing).

We continue to believe that function implementations of these
operations should be allowed, but that implies at a minimum that
different "iord" and "iordbuf" names must exist for different sizes:
"iord" for "int" and smaller sizes, "iordl" for "long int", etc.

* There is little purpose to standardizing the function-like macros
"io_abs_init", "io_abs_release" (4.3.3), and "io_abs_remap" (4.3.4), for the
following reasons:
* The circumstances in which these macros can be used and what they
do (particularly "io_abs_remap") are all highly system-dependent.
* In portable device-driver code, uses of these macros could
just as easily be replaced by calls to ad-hoc functions (e.g.,
"initUARTRegs", "remapUARTRegs"), with definitions for these
functions provided in the local "iohw_ta.h" header as needed.
Performance of these functions is rarely going to be a critical
concern; however, if it is, they can be implemented as macros or
inline functions in "iohw_ta.h".

Removing the "io_abs_" macros from the technical report would not
preclude them from being standardized at a later time if sufficient
prior art develops to make it worthwhile.

Annex B, Embedded systems extended memory support
* We question whether it is necessary to suggest a means of defining
application-defined address spaces in this report (B.1.2).
Since important details of the suggested pragma are left as
implementation-defined anyway, there is little standardization
value in presenting it.  Implementations can already support such
mechanisms as value-added extensions without requiring explicit
sanction from the WG14 committee.

Annex D, Generic "access_spec" descriptor for I/O hardware addressing
* If the report is going to propose a "consistent and complete
specification syntax for I/O registers and their access methods", it
should not be this syntax.  Besides our general objection to pragmas
that define identifiers, we feel the system being proferred is too
ad-hoc and could be better designed.  If a better system cannot be
substituted in place of the current contents, this annex should be
tabled for further study.

__X__  editorial:
* Some implementation-specific characteristics are labelled in the document
as being "implementation-defined" when they probably should not be.

Section 2, Fixed-point arithmetic:
* Minor issue:  To clarify how the fixed-point features are intended
to be used, the main body of the report should include an example of
calculating a scaled dot-product of two "fract" vectors.  Code for
this could be:

fract a[N], b[N];
long accum acc = 0;
for ( int ix = 0; ix < N; ix++ ) {
acc += (long accum) a[ix] * b[ix];
       }
fract z = acc >> SCALE;
(This example is without any explicit rounding and with default
overflow handling.)

* Minor issue:  Versions of the "round" functions for unsigned fixed-
point appear to have been left out of Section 2.1.7.2.
In Section 2.2 on specific changes:
* Paragraph 3 of Section 6.7.2 should not be changed to read

The type specifiers "_Fract", "_Accum", "_Complex" and
"_Imaginary" shall not be used if the implementation does not
provide those types.

In the context of the technical report, the implementation is
already assumed to provide all the fixed-point types.  For the same
reason, Section 6.7.3 should not include the sentence

The type qualifiers "_Sat" and "_Modwrap" shall not be used if
the implementation does not provide those qualifiers.

Section 4, Basic I/O hardware addressing
* Minor issues:  The "iohw_ta.h" header file used in examples is not a
standard header file, and so the proper syntax is
#include "iohw_ta.h"
not
#include <iohw_ta.h>
This occurs in the annexes, too.  Also, it is not obvious to us what
the "ta" stands for.

* Section 4.2.6's exposition on "access_base_spec"s is not as clear as
it needs to be.
* Section 4.3.4 states

Use of "io_abs_remap" and "access_base_spec"s often provides a
faster alternative than passing an "access_spec" as a function
parameter.

Earlier the report calls "access_spec"s macros (4.2.5).  We don't
understand how a macro could be passed as a function parameter.

Annex B, Embedded systems extended memory support
* Minor issue:  There is a Section B.1 but no B.2 or higher.