The following issue has been SUBMITTED.
==
http://austingroupbugs.net/view.php?id=1199
==
Reported By:bhaible
Assigned To:
==
Project:1003.1(2016)/Issue7+TC2
Issue ID: 1199
Category: System Interfaces
Type: Error
Severity: Editorial
Priority: normal
Status: New
Name: Bruno Haible
Organization: GNU
User Reference:
Section:strfmon
Page Number:2039 to 2043
Line Number:65327 to 65492
Interp Status: ---
Final Accepted Text:
==
Date Submitted: 2018-08-12 19:23 UTC
Last Modified: 2018-08-12 19:23 UTC
==
Summary:strfmon, if standards compliant, produces highly
misleading results
Description:
The following program shows strfmon results in the C locale:
===
#include
#include
#include
int main ()
{
char buf[80];
printf ("currency = |%s|\n", localeconv()->currency_symbol);
printf ("positive sign = |%s|\n", localeconv()->positive_sign);
printf ("negative sign = |%s|\n", localeconv()->negative_sign);
strfmon (buf, sizeof (buf), "%^#5.0n", 123.4);
printf ("strfmon result for positive value = |%s|\n", buf);
strfmon (buf, sizeof (buf), "%^#5.0n", -123.4);
printf ("strfmon result for negative value = |%s|\n", buf);
strfmon (buf, sizeof (buf), "%.2n", 123.5);
printf ("strfmon result with 2 fractional digits: = |%s|\n", buf);
}
===
The result on AIX 7.1 is:
currency = ||
positive sign = ||
negative sign = ||
strfmon result for positive value = | 123|
strfmon result for negative value = | 123|
strfmon result with 2 fractional digits: = |12350|
This is POSIX compliant, as far as I can see. However, without a
distinction between positive and negative values, and without a visible
decimal separator, this behaviour is useless, or even dangerous (if a
programmer was not aware of this behaviour and has not worked around it).
The result on glibc 2.23 is:
currency = ||
positive sign = ||
negative sign = ||
strfmon result for positive value = | 123|
strfmon result for negative value = |- 123|
strfmon result with 2 fractional digits: = |123.50|
This is not POSIX compliant, because in the negative value case, it shows a
'-' sign, although localeconv()->negative_sign is the empty string (which
is mandated by POSIX
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_03_01
).
The result on Solaris 10 is:
currency = ||
positive sign = ||
negative sign = ||
strfmon result for positive value = | 123|
strfmon result for negative value = |- 123|
strfmon result with 2 fractional digits: = |123.50|
This is not POSIX compliant, 1. because of the '-' sign, 2. because it
produces
a different number of characters in the negative and in the positive case,
which is against what POSIX says for the '#' flag (lines 65387 to 65389):
To ensure alignment, any characters appearing before or after the
number in the formatted output such as currency or sign symbols are
padded as necessary with characters to make their positive
and negative formats an equal length.
The result on macOS 10.13 is:
currency = ||
positive sign = ||
negative sign = ||
strfmon result for positive value = | 123 |
strfmon result for negative value = |( 123)|
strfmon result with 2 fractional digits: = |123.50|
This is not POSIX compliant, because the test program does not specify the
'+' nor '(' flag, and POSIX says (lines 65363 to 65366):
If '+' is specified, the locale's equivalent of '+' and '-' are
used (for example, in many locales, the empty string if positive and '-'
if negative). If '(' is specified, negative amounts are enclosed within
parentheses. If neither flag is specified, the '+' style is used.
In summary, out of four implementations, only one is POSIX compliant, and
it produces highly misleading / dangerous results.
Desired Action:
Remove strfmon and strfmon_l from the standard. Also remove
from the standard, since its only purpose is the declare these functions.
Or otherwise, change the standard so that the glibc results become the only
compliant results.
==
Issue History
Date ModifiedUsername FieldChange