Bug 166735 - std::showbase fails for hex value 0
std::showbase fails for hex value 0
Status: CLOSED NOTABUG
Product: Fedora
Classification: Fedora
Component: gcc4 (Show other bugs)
4
i386 Linux
medium Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
:
: 166736 167367 (view as bug list)
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2005-08-24 22:08 EDT by D. Stimits
Modified: 2007-11-30 17:11 EST (History)
1 user (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2005-08-26 07:09:03 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description D. Stimits 2005-08-24 22:08:54 EDT
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.8) Gecko/20050511

Description of problem:
std::showbase combined with std::hex in <iostream> fails to show the base if the value is 0. The following program should produce "0x0" as the output in all lines which start with:
std::cout << std::hex << std::showbase...

Instead this program produces output "0", skipping the "0x" base.

// main.cxx
#include <iostream>

int main()
{
   unsigned int var = 0;
   std::cout << var << "\n";

   // This is a failure line, it outputs "0" instead of "0x0".
   std::cout << std::hex << std::showbase << var << "\n";

   var = 1;
   std::cout << var << "\n";
   std::cout << std::hex << std::showbase << var << "\n";

   return 0;
}


Version-Release number of selected component (if applicable):


How reproducible:
Always

Steps to Reproduce:
1. Use std::hex and std::showbase in a std::cout, then feed 0 to the stream.
  

Actual Results:  Outputs "0".

Expected Results:  Outputs "0x0".

Additional info:

gcc-c++-4.0.1-4.fc4
Comment 1 D. Stimits 2005-08-24 22:43:08 EDT
*** Bug 166736 has been marked as a duplicate of this bug. ***
Comment 2 Jakub Jelinek 2005-08-25 02:38:38 EDT
Doesn't sound like a bug to me.
ISO C++98, 22.2.2.2.2/10 says std::showbase means prepending # printf conversion
qualifier.  22.2.2.2.2/7 says std::hex means the printf conversion specifier is
%x.
So the behaviour is IMHO required to be the same as printf ("%#x", 0);
But http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html
says:
"For x or X conversion specifiers, a non-zero result shall have 0x (or 0X)
prefixed to it."
The same is in ISO C99, 7.19.6.1(6):
"For x (or X) conversion, a nonzero result has 0x (or 0X) prefixed to it."

Can you explain why you think C++ should output there 0x0 and back it up
with standard references?
Comment 3 D. Stimits 2005-08-25 18:55:12 EDT
None of the C++ standards mention alternate behavior with 0. Nor does
Stroustrup. It is not possible to find mention of this exception without
consulting C standards, but this isn't C. Stroustrup does not make any
comparison at all to '#' format in C.

In Stroustrup, 3rd edition, section 21.4.6.2, the comment on showbase is:
// on outout prefix oct by 0 and hex by 0x
...Stroustrup does not recognize the 0 exception.

Now I have trouble getting current standards on a subscription basis, but I
believe the wording relative to this is unchanged. My references are in an older
book (which should remain the same with regard to this issue), The Draft
Standard C++ Library, by P.J. Plauger. This book mentions the fprintf topic, but
I'll start by quoting their own showbase definition in the <ostream> chapter,
page 233, section "Using <ostream>":
"showbase: whether ocatal values have a leading 0 or hexadecimal values have a
prefix 0x or 0X, by setting the format flag showbase."
...this definition does not mention alternate behavior for a special case of 0.

Going back to standards chapter on <ios>, this is where the comparison is made
to fprintf. The exact text is:
"showbase: showbase determines whether an integer inserter generates the prefix
0x or 0X for base 16 conversion, or 0 for bas8 conversion (the same as the *
conversion qualifier for fprintf)."

Well, technically, the wording is simply misleading, as the only qualities
mentioned prior to fprintf is to use 0x notation or not...it mentions no special
behavior. It is more likely that one of several things happened, and not the
intent to mark 0-behavior as an exception: (a) the author was not cognizant of
the 0 exception, or (b) the author was cognizant but was only making a
comparison within the context of the text surrounding the statement (which had
no context at all about 0-exceptions).

Without actually contacting the original author of that statement, or perhaps
Stroustrup, the fprintf comparison can at best be considered vague. It is my own
belief that if the behavior is not available and not mentioned in the C++
standard, that no C standard should override C++ standards, as this is not C. My
explanation of this fprintf mention is that it was a statement of heritage which
offers insight into the origins of this specification; but just as an english
language dictionary gives origins of words in terms of latin and greek, I
consider the latin and greek as ancestors, and not the final
definition...english is not latin nor is it greek. And c++ is not c.

That said, if the choice is to not use 0x on 0 values, the standard itself is
broken by use of vague and non-definitive statements. The chance of my
participating in a new C++ standard to fix the language of the statement to
something concrete is less than the proverbial snowball's chance in hell.
Comment 4 Jakub Jelinek 2005-08-26 07:09:03 EDT
The C++ standard references ISO/IEC 9899:1990, see [intro.refs]/1 and /2.
Particularly in /2, references to the standard C library behaviour are
standardized by ISO C90.  Now, ISO C++98 in [22.2.2.2.2]/2 when describing
behaviour of num_put virtual functions says: "
The details of this operation occur in several stages:
- Stage 1: Determine a printf conversion specifier spec and determining the
  characters that would be printed by printf(27.8.2) given this conversion
  specifier for
              printf(spec, val)
  assuming that the current locale is the "C" locale.
- Stage 2: Adjust the representation by converting each char determined by
  stage 1 to a charT using a conversion and values returned by members of
  use_facet<numpunct<charT> >(str.getloc())
- Stage 3: Determine where padding is required.
- Stage 4: Insert the sequence into the out.
".
and from [22.2.2.2.2]/5 to [22.2.2.2.2]/10 paragraphs you can find out that
Stage1 for your testcase is supposed to use "%#x" spec.
Comment 5 Jakub Jelinek 2005-09-02 02:41:27 EDT
*** Bug 167367 has been marked as a duplicate of this bug. ***

Note You need to log in before you can comment on or make changes to this bug.