View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0002000 | 1003.1(2024)/Issue8 | System Interfaces | public | 2026-09-17 19:23 | 2026-11-10 02:35 |
| Reporter | kre | Assigned To | msbrown | ||
| Priority | normal | Severity | Objection | Type | Error |
| Status | Interpretation Required | Resolution | Accepted As Marked | ||
| Name | Robert Elz | ||||
| Organization | |||||
| User Reference | |||||
| Section | XSH 3.strfmon | ||||
| Page Number | 2129-2133 | ||||
| Line Number | 69523 69524-69526 69529 69537-65538 69540-69542 69545-69546 69557-69558 69560-69561 69567-69571 69577 69581-69590 69591-69594 69598 69613-69616 69628-69630 69632-69670 69640-69651 69672-69676 69678-69680 69684-69686 | ||||
| Interp Status | Proposed | ||||
| Final Accepted Text | 0002000:0007531 | ||||
| Summary | 0002000: XSH 3/strfmon misses info and needs attention | ||||
| Description |
| ||||
| Desired Action |
| ||||
| Tags | issue9 | ||||
|
|
All suggested wordings can obviously be improved for spelling, grammar, better standards-speak, etc. Please don't reduce precision when so doing. The suggested changes: #1) is from issues 12 and 13. I'd hope there's nothing controversial about that. Part of the change might give rise to "Of course, that's obvious" -- I don't believe in such things, nothing is too obvious to be explicit about. There is also no "output stream" involved, the output is to an array of bytes. #2 is from issues 3, 4, 5, 6 probably, maybe more. The wording suggested can probably be improved. This one is assuming that the objective is to produce nicely aligned printed (or displayed) output, not anything where particular byte offsets in the result have any particular meaning. #3 is issue 3, or a part of it. Issue 5 as well. In particular, regardless what criteria are to apply to the fill character, making the behaviour undefined if those are not met is absurd. All the implementation should ever do is insert N copies of the fill character (calculated as described in change #12). That might have the effect of not producing nicely aligned results as expected, but that's hardly undefined behaviour as the standard defines that phrase. Nor is it even unspecified, or implementation defined. It's just not what the application was hoping for. #4 is part of issue 6, and just a general tidying of the language, for added precision. #5 is issue 10. #6 is more general cleanup for better precision. #7 is issue 10 (again). #8 is more that perhaps should have been added by 0001199, and issue 2. #9 is more of issue 3. #10 is just a wording cleanup, related to a part of issue 3 (the numeric fill character has a name, and "special character" is not it!) #11 and #12 (which go together) are from issue 6. By all means improve the wording of #12. #13 is issue 4. Also more of issue 3. #14 is issue 1. Choice 1 for this one seems obvious to me, if there is no monetary decimal point character in the locale, then clearly the locale does not want fractional currency values. If it simply prefers to have no fractions, in the normal case, it can set frac_digits to 0, then the application can override that with an explicit precision. setting the decimal point to "" should thus mean "never have fractional values for this locale". However it seems relatively common in implementations to simply use the numeric decimal point if the monetary one is not defined. Personally I see no justification for that at all (even though it is what NetBSD's implementation does (or did)). Note that if you choose choice 2, then you MUST pick one of the others (1 (though that would be unlikely if the aim is to allow some decimal point string), or one of 3..7). Despite how it may appear, the standard does not require a locale to have a non-empty numeric decimal point character - it requires localedef to reject a specification where a non-empty numeric decimal point character is not defined, but nowhere does it require an implementation to use localedef when generating locale data, just that it be available to be used if desired. What's more, if it did, the POSIX (aka C) locale would be unable to be created, as that one violates all kinds of constraints imposed upon locales that localedef deals with. Choices 3 and 4 would be perhaps plausible (after all, strfmon defines "-" as a plausible negative sign should none be provided) - perhaps as follow-ons to choice 2. The rest of the choices, while possible, are absurd. #15 is just a minor cleanup, adding some precision - making it clear that the numeric decimal point is not a fallback for the monetary decimal point (perhaps the wording for that could be better). Of course should you choose choice 2 for action #14, then this one should probably be ignored. #16 is issue 8. #17 is issue 7 (or part thereof). #18 is more from issue 7. #19 is simply a grammar fix (should perhaps have been submitted as a separate "Editorial" defect report, but it seemed saner to deal with it at the same time as everything else). #20 is issue 11. #21 is more from issue 11. The actual examples will depend upon the resolution of issue 1 (action #14). #22 is kind of a follow-on to issues 9 and 8, and a correction to what is currently implied by the text. Trying with the '+' flag if a sign is wanted, is clear enough, but omitting the '+' flag and "parentheses are acceptable" are unrelated concepts, parentheses will only be used when there is no + or ( flag given, if the locale has one (and only one) of its [int_]p_sign_posn and [int_]n_sign_posn, set to 0. Both 0 and the the parentheses would be useless (this is another case just like having the positive_sign and negative_sign both empty, or identical, and makes using parentheses useless as well. But if neither of the [int_]p|n_sign_posn values is 0, parentheses won't be used, so the text "but parentheses are acceptable" is misleading. Instead, omitting the + just allows strfmon() to format the value in locales like the POSIX locale, when none of the LC_MONETARY values provides much, or any, assistance at all, while generating something reasonable. #23 is a follow-on to #22, and also relates to issue 7, and specifies how an application, for which "parentheses are acceptable" might achieve that if using the + flag fails (by using the '(' flag instead). The '(' flag also ends up (as a result of action #6) being defined in such a way that it always works (always uses (n) for negative values and just p for positive ones, regardless of what the locale specifies (or doesn't). #24 is a (potential) consequence of action #17 (issue 7), and depends upon what the resolution of the [EINVAL] issue turns out to be. #25 is a bonus extra - no issue for this one. However, dividing number/ name spaces into pieces for use by different kinds of users, when done by a standards organisation, is doomed to always either fail, or cause problems. The whole basis for the standard is to specify what the applications can expect to have happen for specific actions they take, and to tell the implementers what they need to do to produce those results. If an implementer sees the existing FUTURE DIRECTIONS and has a need for a new conversion character (perhaps to generate values in units of millions, or something, with an 'M' suffix/prefix somewhere) and does as advised by picking an upper case character for that conversion (here, probably 'M'). That's fine, they do that, and this group won't accidentally allocate M to some other use. But this implementation's new feature becomes popular, and ends up copied by all of the other implementations, because applications want to use it (assuming one can find an application that uses strfmon()!). What happens next? Clearly the new conversion character needs to be standardised. And to be compatible with what every implementation has implemented, it would need to use the 'M' as the conversion character. But the existing FUTURE DIRECTIONS says "no" to that, the standard must use a lower case character. So, we either do what it says, in which case the standard is promising an action that no implementation supports (not good, and leads to implementers needing to provide both - the conversion character the applications all use, along with the one the standard defines for the purpose - that's simply wasteful and stupid), or the standard just ignores the FUTURE DIRECTIONS and does the sane thing in a case like this. If that is to be what is likely to happen, there is no point having the FUTURE DIRECTIONS so let's just delete it now, and be done with it. Beyond that, the more likely things for an implementation to want to add, are more flag characters. After all, the difference between the conversion characters are whether they are national or international conversions ... what else could there be? Extra-terrestial currency conversions? Household currency conversions? None of that is likely, and the 'M' mooted above is more likely to be implemented as a flag, than as a conversion specification (I see no reason why an alphabetic flag can't be used - just as long as it can't be confused with a conversion character). For that usage, there's no guidance as to what new flag characters implementations might add, whilst avoiding conflicts with any new flag characters added in the standard. Since (I submit) new flags are far more likely than new conversion characters, the current FUTURE DIRECTIONS is simply useless, even if you don't agree with the argument in the previous paragraphs. There is no resolution provided for issue 14. Good luck with that one. |
|
|
Interpretation response ------------------------ The standard is unclear on this issue, and no conformance distinction can be made between alternative implementations based on this. This is being referred to the sponsor. Rationale: ------------- Existing implementations have extended the description provided. Notes to the Editor (not part of this interpretation): ------------------------------------------------------- Make the following changes, all in the XSH section 3 group of pages for strfmon (pages 2129-2133).
|
|
|
Interpretation proposed: November 4 2026 |
|
|
The proposed resolution needs some obvious corrections. First, item 22, says "On page 2133 on line 69676, after the end of the existing sentence, but within the same paragraph, add the first, or both, of the following two new sentences:" - that is not an instruction to the editor, but a request for the editor to decide what to do. Given the other changes adopted, I would expect that should be changed to: "On page 2133 on line 69676, after the end of the existing sentence, but within the same paragraph, add the following two new sentences:" (or any equivalent wording). Second: In item 14, you decided that if no mon_decimal_point is defined, the locale's LC_NUMERIC decimal_point setting should be used as the mon_decimal_point (which is fine, it allows decimal output in the C locale if requested by the format string) - but it is not what I expected the choice to be which was reflected in the examples added in item 20 of the resolution. In particular the example for the "%.2n" format should now produce 2 decimal places in the results in all cases, with '.' as the decimal point. I have yet to check the others to validate that they all remain correct. While those are clear issues that need correcting, I also still believe that making the behaviour undefined in the resolution number 3 is overly draconian. It could be unspecified if an even less specific result (which would be vaguer to be sure) is unacceptable. But "undefined" for this is absurd. |
|
|
I also see several instances of very poor grammar in the proposed new text - most of those probably stemming originally from my Desired Action text (there gets to be a point when writing something that long that going back one more time to re-read and correct it just gets to be too much). Those I think could be left for the editor to fix -- the intended meaning is obvious, the proposed words simply don't make acceptable English text --- or if it is preferred, I could supply corrections. |
|
|
I have run the examples to be added for the C (POSIX) locale through my updated test program, with a strfmon() updated to match the decision to allow the LC_NUMERIC decimal point to be used if there is no LC_MONETARY mon_decimal_point defined. They agree with the earlier examples (provided in the Desired Action, and incorporated into 0002000:0007531 (the proposed resolution) except for the results for the "%.2n" format string, where the results should be:
|
|
|
In 0002000:0007531 item 13, the text of the third sentence proposed to be added is:
but that is poor grammar. The original form of the sentence started "Only if" rather than just "If", and that could be replaced to improve things, but I now suggest that sentence be changed to be:
which I think better expresses the intent of the exception to things being nicely aligned. In the case where no left precision is specified, no alignment is ever to be expected, so I don't think that case needs mentioning. |
|
|
In 0002000:0007531 item 17, the decision to allow EILSEQ for badly encoded character data in the locale's definition is OK, though my implementation does not generate that - it simply treats badly encoded data as if it did not exist, but the way this is written I do not believe can be correct:
Imagine an application, which for whatever bizarre reason has set LC_CTYPE to zh_CN.GB2312 and has LC_MONETARY set to de_DE.UTF-8. Does the committee really believe that the encodings of the characters in values like the mon_thousands_sep (or decimal point, etc) should be GB2312 in that German locale? Or is it the intent that when obtaining locale values, the implementation must transcode all string values into the current LC_CTYPE locale's encoding (and language??) I'd suggest that similar wording be used as was added in the proposed resolution item 14, where it is the mon_decimal_point from the LC_NUMERIC category of the locale set for LC_MONETARY that is used, not whatever the current LC_NUMERIC setting happens to be. |
|
|
This is a test note, please ignore. |
|
|
KRE: Actions to be taken: 0002000:0007531 will be edited in place to add the following corrections: Correcting item 22 i change the instruction On page 2133 on line 69676, after the end of the existing sentence, but within the same paragraph, add the following two new sentences: Correcting item 20 in the same bugnote: change the example to be: %.2n [123.45] Use the POSIX locale LC_NUMERIC decimal_point [-123.45] [3456.78] Correcting item 13 in the same Bugnote: Change: If the Left Precision was not specified, or was specified and was not large enough for the value, the resulting width may differ from the length produced by any other value for which the Left Precision is sufficient. (Rationale for this one, we did want to say this but the word "may" was in the wrong place and you caught that). For 0002000:0007549, we need more clarification on the exact change you are suggesting, if you could. |
|
|
For 0002000:0007549 the text I would suggest adding would be something like
But that's just the beginning of locale related issues, for which I don't have answers. More coming in another note later (I had yet another "session timeout" - invalid security parameter, when attempting a much longer version of this note - to try and explain what I see as the harder problems, so that is going to need to wait. |
|
|
Also, just to avoid this falling through the cracks, in 0002000:0007531, item #3 in the list of changes to make, in the proposed new text to be inserted, I would change the last wordsif not, the behavior is undefined.to be if not, the behaviour is unspecified (and no, the spelling of "behaviour" is not the issue, leave out the 'u' if you really must). If there is some justification for making it undefined when the character given after the '=' flag is not a 1 column wide character, I'd like to know what it is. As I see it, the implementation has 3 rational choices - it can check the width of the character, and simply refuse to use it (either generating EINVAL or silently ignoring the flag and just using <space>), or it can ignore the issue, and simply use whatever (valid) character is given, inserting N 2-column characters (or 3 or 4, or even 0) where N columns need to be filled, resulting in ugly results, or the implementation can try hard to do what has been requested, when N columns need to be filled, with a fill character that is W columns wide, insert N/W copies of the fill character (or 0 if W==0), and then fill any columns remaining: N if W==0, or N%W (or maybe it is N-N%W - I can't be bothered checking the arithmetic) with spaces. It is very hard to imagine anything different the implementation can do, and if the standard does not specify one of those as the one true way, then that might count as unspecified behaviour (as it will not be specified), but nothing there rises to being undefined behaviour. Note none of this has anything whatever to do with the number of bytes needed to encode the fill character, a one column wide character may be represented (using UTF-8) as anything from 1 to 4 bytes, and implementations are expected to cope with whatever is needed there - if the resulting output exceeds maxsize then an E2BIG will result - that part is straightforward. |
|
|
> Does the committee really believe that the encodings of the characters in values like the mon_thousands_sep (or decimal point, etc) should be GB2312 in that German locale? I don't think that's what that text was suggesting. mon_thousands_sep is not interesting since in de_DE.UTF-8 it's just going to be '.', but suppose we're talking about currency_symbol which will be "\342\202\254" ("€" in UTF-8) which is not a valid byte sequence in GB2312. I don't think the text was saying that "€" could be re-coded in GB2312 by some implementation (the character doesn't exist there anyway), I think the text was saying it is valid for an implementation that internally uses wide characters to fail to decode this byte sequence and return the error to the caller. This would also be useful for the application, as otherwise the application would just be given a series of bytes that do not form valid characters and would result in errors later on. |
|
|
Re 0002000:0007555 - I agree, using the German locales as an example was a poor choice, those are far too mundane to cause issues, a French locale might be better, I believe that a "narrow non-breaking space" is the French generic thousands separator (which unicode code point is the appropriate one, I don't know, our French locale simply uses a normal width non-breaking space, code point 160, or in UTF-8 \302\240 (two bytes). Whatever the intent of the text in question, it wasn't specifying anything useful, as attempting to encode locale data for some locale using some other locale's character encoding is patently absurd. A much bigger locale related issue will address that (which has a very simple solution, unlike other issues with locales) - it doesn't need to be addressed here, just not incorrectly worded. But the substance of your point is a good one, and one I attempted to raise in my first attempt at 0002000:0007553 (the one Mantis wouldn't accept - because of its timeout) and relates to in what encoding the results from functions like strfmon() (but also XSH/printf and many others) are supposed to render their results. I know that our implementation doesn't care what the encoding of the decimal point or thousands separator characters are (or the mon_* versions for strfmon) - it simply copies whatever the locale specifies as that string into the formatted result, with no regard at all what LC_CTYPE might be, and whether or not it specifies the same encoding as LC_NUMERIC or LC_MONETARY. This might turn out to be a huge problem to fix, or it might be simple, and simply result in making things unspecified whenever conflicting encoding types or character sets have been selected via setlocale() (or equivalents). None of that is stfrmon() specific however. |
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2026-09-17 19:23 | kre | New Issue | |
| 2026-09-17 19:28 | kre | Note Added: 0007502 | |
| 2026-10-12 16:17 | msbrown | Tag Attached: issue9 | |
| 2026-10-19 19:26 | msbrown | Assigned To | => msbrown |
| 2026-10-19 19:26 | msbrown | Status | New => Interpretation Required |
| 2026-10-19 19:26 | msbrown | Resolution | Open => Accepted As Marked |
| 2026-10-19 19:26 | msbrown | Interp Status | => --- |
| 2026-10-19 19:26 | msbrown | Note Added: 0007531 | |
| 2026-11-04 14:48 | agadmin | Interp Status | --- => Proposed |
| 2026-11-04 14:48 | agadmin | Final Accepted Text | => 0002000:0007531 |
| 2026-11-04 14:48 | agadmin | Note Added: 0007542 | |
| 2026-11-06 21:26 | kre | Note Added: 0007545 | |
| 2026-11-06 21:43 | kre | Note Added: 0007546 | |
| 2026-11-09 01:51 | kre | Note Edited: 0007545 | |
| 2026-11-09 02:02 | kre | Note Added: 0007547 | |
| 2026-11-09 02:48 | kre | Note Added: 0007548 | |
| 2026-11-09 03:33 | kre | Note Added: 0007549 | |
| 2026-11-09 03:36 | kre | Note Edited: 0007549 | |
| 2026-11-09 03:37 | kre | Note Edited: 0007549 | |
| 2026-11-09 15:26 | msbrown | Note Added: 0007550 | |
| 2026-11-09 16:39 | msbrown | Note Added: 0007551 | |
| 2026-11-09 16:43 | msbrown | Note Edited: 0007531 | |
| 2026-11-09 16:49 | msbrown | Note Edited: 0007551 | |
| 2026-11-09 16:49 | msbrown | Note Edited: 0007531 | |
| 2026-11-10 00:57 | kre | Note Added: 0007553 | |
| 2026-11-10 01:23 | kre | Note Added: 0007554 | |
| 2026-11-10 01:25 | hvd | Note Added: 0007555 | |
| 2026-11-10 01:26 | hvd | Note Edited: 0007555 | |
| 2026-11-10 02:30 | kre | Note Added: 0007556 | |
| 2026-11-10 02:35 | kre | Note Edited: 0007556 |