Submitter: Josey (US)
Submission Date: 2005-09-28
Reference Document: N1138
Subject: Potential problems with TC2 #34, #35, and #36
Summary: The imaginary macro is missing in the normative text.
I think there may be a problem here with C99 (as amended by
TC2). As far as I can see there is no longer any mention of the
imaginary macro in normative text, which means implementations
are not allowed to define it (because it is not reserved for
use by the implementation). Yet in Annex G it still recommends
(in informative text) that implementations which define
__STDC_IEC_559_COMPLEX__ should define the
imaginary macro. It also recommends that these implementations
I "to be
_Complex_I as stated in 7.3)". Yet
implementations that do so would not comply with the normative
text in 7.3 which requires I to be defined as
Assuming that the intention was to allow implementations to follow the recommendations in Annex G, but by an oversight the necessary normative text to allow them to do so was omitted from TC2, perhaps in POSIX we should keep the current text but mark some of it CX?
Suggested Technical Corrigendum
Committee Discussion (for history only)
It was pointed out that implementing Annex G causes nonconforming changes to the normative text in C99. Exact instances were not given or known. The implications of NOT allowing 'I' to expand to '_Imaginary_I' are not readily clear.
We did not fully realize the repercusions of the changes that DR 207 would do (implementing Annex G and
Some members of the committee had hoped that imaginary would be ignored and go away. However, at least one vendor has shipped an implementation that supports imaginary and Annex G. This vendor has indicated that it would not be hard to modify its implementation so that it passes strict conformance with one command line switch and offer a default implementation with imaginary without that switch.
One problem with I being imaginary versus complex is f(I) is either passed one double or two doubles. However, this only matters to a few type generic math functions and no user functions (since users have no means to define their own type generic functions). One such type generic math function is cosh(), i.e., cosh(I*y) is the real cos(y) if I is imaginary, but is the complex cosh(z) if I is complex.
It has been observed that the relational operators (<, <=, >=, >) of 6.5.8 and comparison macros of 7.12.14 (isless, ...) should be allowed to be used with imaginary types when both operands are imaginary; this was an oversite in the original C99 specification.
The mimimal changes to restore back to C99 w.r.t. to DR 207 is restore paragraphs 3, 4, and 5 of 7.3.1 of C99; this is a subset of the changes done by DR 207 in TC2.
In 7.3.1 of C99+TC1+TC2, replace paragraphs 3 and 4 with:
[#3] The macrosimaginaryand_Imaginary_Iare defined if and only if the implementation supports imaginary types;165 if defined, they expand to _Imaginary and a constant expression of type const float _Imaginary with the value of the imaginary unit.
[#4] The macroIexpands to _Imaginary_I or _Complex_I. If _Imaginary_I is not defined, I shall expand to _Complex_I.
[#5] Notwithstanding the provisions of subclause 7.1.3, a program may undefine and perhaps then redefine the macros complex, imaginary and I.
165A specification for imaginary types is in informative annex G.