隐式转换被认为是一个坏概念吗?

Is implicit casting considered to be a bad concept?

为什么甚至允许隐式转换?我的意思是将 float 隐式转换为 int 有什么好处?显式转换不会使代码更具可读性和更易于调试吗?

回答:是的,这是一个例子

#include <stdio.h>

int main()
{
  unsigned int a=1;
  int b=-1;
  if(b>a)
     printf("-1 > 1 \n");
   else 
     printf("boring!\n");

return 0;
}

如果你执行这段代码,你会得到

-1 > 1

这是由于变量 b 的隐式转换(b 将转换为 unsigned int 并将 -1 转换为 4294976295 这是大于 1) 有时会产生问题,因此进行显式转换是一个好习惯,以便为您和从事同一项目的程序员弄清楚事情!!

问题:

Why is implicit casting even allowed? I mean what is the benefit of casting a float to an int implicitly?

C FAQ 的维护者 Steve Summit 在 tutorial 中说:

The default conversion rules serve two purposes. One is purely selfish on the compiler's part: it does not want to have to know how to generate code to add, say, a floating-point number to an integer. The compiler would much prefer if all operations operated on two values of the same type: two integers, two floating-point numbers, etc. (Indeed, few processors have an instruction for adding a floating-point number to an integer; most have instructions for adding two integers, or two floating-point numbers.) The other purpose for the default conversions is the programmer's convenience: the mentality that ``the computer and the compiler are stupid, we programmers must specify everything in excruciating detail'' can be carried too far, and it's reasonable to define the language such that certain conversions are performed implicitly and automatically by the compiler, when it's unambiguous and safe to do so.

问题 2:

Doesn't explicit casting makes a more readable and easier to debug code?

答案:

As mentioned above this is how implicit conversions happen but explicit conversions "YES" adds readability.

第一:C++中大量的隐式转换是由于 历史原因,没有别的。我认为没有人考虑 他们都是个好主意。另一方面,有许多不同的 类型的隐式转换,其中一些几乎是必不可少的 语言:如果你需要显式转换,你不会喜欢它 将 MyType x; 传递给采用 MyType const& 的函数;我很漂亮 确保有一个共识,即 const 转换添加 const,比如 这个,应该是隐式的。

关于未达成共识的转化:

  • 几乎没有人对无损转换有问题; intlong,或 floatdouble。大多数人还 似乎接受从整数类型到浮点数的转换(例如 intdouble),尽管在某些情况下这些可能会降低精度。 (例如int i = 123456789; float f = i;。)

  • 在 C++98 的标准化过程中有一个建议弃用 缩小转换范围,例如 floatint。 (该书的作者 提议是 Stroustrup;如果你不喜欢这样的转换,你在 好公司。)它没有通过;我不知道为什么,但我怀疑 这是一个过多地打破 C 语言传统的问题。 在 C++11 中,这种转换 在某些较新的构造中是 禁止的, 就像新的初始化序列一样。所以听起来好像有 一致认为这些隐式转换并不是一个好主意, 但由于担心破坏代码或可能只是 打破了 C 中的传统。(我知道不止一些人 不喜欢 someString += 3.14159; 是合法声明这一事实, 在字符串末尾添加一个 ETX 字符。)

  • bool 的原始提案建议弃用所有 数字和指针类型到 bool 的转换。这已被删除; 很快就很明显,如果它提出,该提案将不会通过 if ( somePointer ) 之类的东西(相对于 if ( somePointer != NULL )) 非法。仍然有一个庞大的身躯 考虑此类转换的人(包括我自己)"bad",并避免 他们。

最后:编译器可以自由地对任何感觉发出警告 像。如果市场坚持对此类转换发出警告,编译器 将实施它们(可能作为一种选择)。我怀疑 他们不这样做的原因是这些警告声名狼藉,因为 最初的实现产生了太多的警告。不可缺少的 促销导致许多没人想要的缩小转换 消除:

char ch = '0' + v % 10;

例如,涉及 intchar 的转换(即 缩小);在 C++11 中:

char ch{ '0' + v % 10 };

是非法的(但 VC++ 和 g++ 都接受它,g++ 带有警告)。我 怀疑是可用的,禁止缩小转换至少 由于以下原因,必须对更广泛的类型本身的情况进行例外处理 积分提升、混合类型算术和案例来源 expression 是编译时常量,在目标类型中 "fits"。

显然,破坏旧代码是阻止新版本语言(C 和 C++)更改规则的原因。所以问题是为什么在构思C时首先允许这样做。据我所知,根本原因是 C 被建模为接近硬件,而硬件不(通常,从根本上)区分地址、整数和布尔类型。因此像 int i=10; while(i--) doSomething(i);int *p, offset; ... if(p) doSomethingElse(p+offset); 这样的代码几乎可以直接翻译成机器代码。事实上,它离宏汇编程序不远,主要区别在于函数调用的细节。在我看来,它也非常可读。任何额外的转换或显式比较都会损害逻辑的基本可见性。但这当然是品味和编程社会化的问题。

然后是的,70 年代没有的经验表明,一些隐式转换是错误的来源。如果 K&R 能够再次构思 C,他们可能会改变一些(实际上很少)东西。世界就是这样,尽管我们不得不应付编译器警告。