是std :: showbase和std :: showpos互斥吗? [英] Are std::showbase and std::showpos mutually exclusive?

查看:372
本文介绍了是std :: showbase和std :: showpos互斥吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题产生于一个讨论,我正在使用通常的 ostream&运算符<< (ostream& some; type_)用于C ++中的数字类型。

This question arose from a discussion I was having about the correct way to output a numeric value using the usual ostream & operator << (ostream &, some_type) for a numeric type in C++.

我熟悉std :: showbase和std :: showpos在每个基地,他们基本上是相互排斥的。即:在十进制中,不显示基数,并且在正数上添加+;而在十六进制或八进制中,显示基址,但是不显示+(也不是减号),因为类型的值被打印成类似于转换为无符号类型。

The way I'm familiar with the behavior of std::showbase and std::showpos in each base, they are basically mutually exclusive. That is: in decimal no base is shown, and the '+' is added on positive numbers; whereas in hexadecimal or octal, the base is shown, but a '+' is not shown (nor is a minus), as the value of the type is printed as if it's cast to an unsigned type.

例如,这个简单(详细)程序:

For example, this simple (verbose) program:

#include <iostream>

int main() {
  std::cout << std::dec << std::showpos << std::showbase << int64_t(+5) << std::endl;
  std::cout << std::oct << std::showpos << std::showbase << int64_t(+5) << std::endl;
  std::cout << std::hex << std::showpos << std::showbase << int64_t(+5) << std::endl;
  std::cout << std::dec << std::showpos << std::showbase << int64_t(-5) << std::endl;
  std::cout << std::oct << std::showpos << std::showbase << int64_t(-5) << std::endl;
  std::cout << std::hex << std::showpos << std::showbase << int64_t(-5) << std::endl;
}

使用GCC编译时提供此输出:

Gives this output when compiled with GCC:

+5
05
0x5
-5
01777777777777777777773
0xfffffffffffffffb

这是我一直期望的,使用C ++多年,但这是真的保证标准,这只是常见的行为?例如,一个符合标准的C ++编译器可以输出这些序列之一吗?

This is what I've always expected, having used C++ for many years, but is this really guaranteed by the standard, or is this just common behavior? For example, could a standard-compliant C++ compiler output one of these sequences instead?

+5
+05
+0x5
-5
01777777777777777777773
0xfffffffffffffffb

或者:

+5
+05
+0x5
-5
-05
-0x5


推荐答案

code> ios_base 本身,没有。 showpos showbase 调用单一参数 setf

For ios_base itself, no. showpos and showbase calls the single-argument setf (§27.5.6.1[fmtflags.manip]/5 and /13) on the stream, which the two does not affect each other.

更深入, std :: ostream 使用 locale :: facet :: put 函数打印整数(§27.7.3.6.2[ostream.inserters.arithmetic] / 1)及其实现 locale :: facet :: do_put
(§22.4。 2.2.2 [facet.num.put.virtuals] / 5)指定:

Going deeper, a std::ostream uses the locale::facet::put function to print an integer (§27.7.3.6.2[ostream.inserters.arithmetic]/1), and its implementation locale::facet::do_put (§22.4.2.2.2[facet.num.put.virtuals]/5) specifies:


用于描述阶段1的所有表都是有序的。也就是说,条件为真的第一行适用。

All tables used in describing stage 1 are ordered. That is, the first line whose condition is true applies. A line without a condition is the default behavior when none of the earlier lines apply.

...

转换说明符具有如表90所示的可选附加限定符。

The conversion specifier has the following optional additional qualifiers prepended as indicated in Table 90.


                  Table 90 — Numeric conversions

+-----------------------+-------------------+------------------+
| Type(s)               | State             | stdio equivalent |
+=======================+===================+==================+
|                       | flags & showpos   | +                |
| an integral type      |                   |                  |
|                       | flags & showbase  | #                |
+-----------------------+-------------------+------------------+
|                       | flags & showpos   | +                |
| a floating-point type |                   |                  |
|                       | flags & showpoint | #                |
+-----------------------+-------------------+------------------+

...

阶段1结束处的表示包含将通过 printf(s,val)其中 s 是上面确定的转换说明符。

The representations at the end of stage 1 consists of the char’s that would be printed by a call of printf(s, val) where s is the conversion specifier determined above.

showpos showbase 在同一单元格中,我相信标准隐含意味着他们在(从 std :: cout<< std :: showpos<< std :: showpoint< < 6.0 对于以下行),这两个标志在这里仍然不是互斥的。

Here, we see that showpos and showbase are in the same cell, which, I believe the standard implicitly mean that they're in the same "line", and thus both applies (it can be seen from std::cout << std::showpos << std::showpoint << 6.0 for the following "line"), and the two flags are still not mutually exclusive here.

到目前为止,我们看到 showpos showbase 在C ++中不是排他的,行为由 printf 定义(虽然实现不需要使用 printf ,例如libc ++使用 sprintf ,而libstdc ++没有) ,我们必须检查C标准。

So far, we see that showpos and showbase are not exclusive in C++, and the actual formatting behavior is defined by printf (though the implementation doesn't need to use printf, e.g. libc++ uses sprintf, while libstdc++ does not), which we have to check the C standard.

在C中,使用 o + showpos c $ c>和 x / X hex )未定义,因为C99§7.19.6.1/ 6和/ 8说

In C, using + (showpos) with o and x/X (oct and hex) is not defined, because C99 §7.19.6.1/6 and /8 says


+


已签署转换始终以加号或减号开头。 ...

The result of a signed conversion always begins with a plus or minus sign. ...

o code>, x X


unsigned int 参数转换为...


参数未签名,因此 + 无法应用。

The argument is not signed, so the + cannot apply. The behavior is not written out, so it is undefined.

添加 showbase )到 d dec )也是未定义的行为,

Adding # (showbase) to d (dec) is also undefined behavior, as clause /6 says:



结果将转换为替代形式。对于 o 转换,...​​对于 x (或 X )conversion ...对于 a A e E f F g G 转换,...​​对于 g code> G 转换... 对于其他转换,此行为未定义。

The result is converted to an "alternative form". For o conversion, ... For x (or X) conversion, ... For a, A, e, E, f, F, g, and G conversions, ... For g and G conversions, ... For other conversions, the behavior is undefined.


糟糕。

因此,不仅两个标志不是互斥的,输出根本没有定义。方案2和3提到的OP可能发生。在gcc和clang中,冲突选项( showpos 代表 oct hex ; showbase dec )被忽略,这给一个错觉的两个选项是互斥,但标准不会保证。

Therefore, not only the two flags are not mutually exclusive, the output is not defined at all. Scenarios 2 and 3 OP mentioned may happen. In gcc and clang, the conflicting option (showpos for oct and hex; showbase for dec) are simply ignored, which gives one an illusion of the two options being mutually exclusive, but the standard will not guarentee that.

(免责声明:我使用n3242和n1124作为参考,最终标准可能不完全一样)

(Disclaimer: I am using n3242 and n1124 as reference, the final standard might not be exactly the same)

这篇关于是std :: showbase和std :: showpos互斥吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆