[1003.1(2016)/Issue7+TC2 0001199]: strfmon, if standards compliant, produces highly misleading results

2018-08-12 Thread Austin Group Bug Tracker


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   

Re: D1095R0/N2xxx draft 4: Zero overhead deterministic failure - A unified mechanism for C and C++

2018-08-12 Thread Niall Douglas
> I think your paper's example should NOT use abs(), but instead some
> other function (whether you merely rename your existing example to
> 'myabs', or pick a different function which DOES have well-defined errno
> semantics right now), precisely because abs() does NOT currently have
> well-defined errno semantics and it is controversial on whether such
> semantics should be given to it.

If that's literally the only feedback, then that's no problem to change.

Niall