我一直认为 C++ 是最强类型的语言之一。
所以我很震惊地看到这篇论文的表 3表明 C++ 是弱类型的。
显然,
C 和 C++ 被认为是弱类型,因为由于类型转换,人们可以将结构的一个整数字段解释为指针。
类型转换的存在是否重要?这种演员表的明确性无关紧要吗?
更一般地说,C++ 是弱类型的真的被普遍接受吗?为什么?
我一直认为 C++ 是最强类型的语言之一。
所以我很震惊地看到这篇论文的表 3表明 C++ 是弱类型的。
显然,
C 和 C++ 被认为是弱类型,因为由于类型转换,人们可以将结构的一个整数字段解释为指针。
类型转换的存在是否重要?这种演员表的明确性无关紧要吗?
更一般地说,C++ 是弱类型的真的被普遍接受吗?为什么?
该论文首先声称:
相反,如果类型混淆可以无声地发生(未被检测到)并最终导致难以定位的错误,则该语言是弱类型的。
然后声称:
此外,C 和 C++ 被认为是弱类型,因为由于类型转换,人们可以将结构的整数字段解释为指针。
这对我来说似乎很矛盾。在 C 和 C++ 中,由于类型转换而可能发生的类型混淆不会无声无息地发生——有一个类型转换!这并不能证明这些语言中的任何一种都是弱类型的,至少不是该论文中的定义。
也就是说,根据论文中的定义,C 和 C++仍可能被视为弱类型。正如已经在对该问题的评论中指出的那样,该语言支持隐式类型转换的情况。许多类型可以隐式转换为bool
,类型的文字零int
可以静默转换为任何指针类型,不同大小的整数之间存在转换等,因此这似乎是考虑 C 和 C++ 弱类型的一个很好的理由论文的目的。
对于 C(但不是 C++),还有更危险的隐式转换值得一提:
int main() {
int i = 0;
void *v = &i;
char *c = v;
return *c;
}
就本文而言,这绝对必须被视为弱类型。位的重新解释是静默发生的,并且可以通过将其修改为使用完全不相关的类型而变得更糟,这些类型具有静默的未定义行为,通常与重新解释位具有相同的效果,但在启用优化时会以神秘但有时有趣的方式爆炸.
不过,总的来说,我认为“强类型”和“弱类型”没有固定的定义。有各种等级,与汇编相比是强类型的语言可能与 Pascal 相比是弱类型的。要确定 C 或 C++ 是弱类型的,您首先必须询问弱类型的含义。
“弱类型”是一个非常主观的术语。我更喜欢术语“严格类型”和“静态类型”与“松散类型”和“动态类型”,因为它们是更客观和更精确的词。
据我所知,人们通常使用“弱类型”作为贬义词,意思是“我不喜欢这种语言中的类型概念”。对于那些无法针对特定语言提出专业或技术论点的人来说,这有点像是一种自言自语(或者更确切地说,是自言自语)。
“严格类型”一词的解释也略有不同。根据我的经验,普遍接受的含义是“如果类型不匹配,编译器会生成错误”。另一种解释是“没有或很少有隐式转换”。基于此,C++ 实际上可以被认为是一种严格类型的语言,而且大多数情况下它也被认为是这样的。我想说的是,关于 C++ 的普遍共识是它是一种严格类型的语言。
当然,我们可以尝试一种更细致的方法来解决这个问题,并说语言的某些部分是严格类型的(这是大多数情况),其他部分是松散类型的(一些隐式转换,例如算术转换和四种类型显式转换)。
此外,还有一些程序员,尤其是对几种语言不熟悉的初学者,不打算或不能区分“严格”和“静态”,“松散”和“动态”,并根据他们有限的经验(通常是流行脚本语言中动态性和松散类型的相关性,例如)将这两个 - 否则正交的 - 概念混为一谈。
实际上,C++ 的某些部分(虚拟调用)要求类型系统是部分动态的,但标准中的其他内容要求它是严格的。同样,这不是问题,因为这些是正交概念。
总而言之:可能没有一种语言可以完全、完美地归入一个或另一个类别,但我们可以说给定语言的哪个特定属性占主导地位。在 C++ 中,严格性确实占主导地位。
相反,如果类型混淆可以无声地发生(未被检测到)并最终导致难以定位的错误,则该语言是弱类型的。
好吧,这可能发生在 C++ 中,例如:
#define _USE_MATH_DEFINES
#include <iostream>
#include <cmath>
#include <limits>
void f(char n) { std::cout << "f(char)\n"; }
void f(int n) { std::cout << "f(int)\n"; }
void g(int n) { std::cout << "f(int)\n"; }
int main()
{
float fl = M_PI; // silent conversion to float may lose precision
f(8 + '0'); // potentially unintended treatment as int
unsigned n = std::numeric_limits<unsigned>::max();
g(n); // potentially unintended treatment as int
}
此外,C 和 C++ 被认为是弱类型,因为由于类型转换,人们可以将结构的整数字段解释为指针。
嗯......不是通过任何隐式转换,所以这是一个愚蠢的论点。C++ 允许在类型之间进行显式转换,但这几乎不是“弱”——它不会像上面网站自己的定义所要求的那样意外/无声地发生。
类型转换的存在是否重要?这种演员表的明确性无关紧要吗?
明确性是一个重要的考虑因素恕我直言。让程序员覆盖编译器的类型知识是 C++ 的“强大”特性之一,而不是一些弱点。它不容易意外使用。
更一般地说,C++ 是弱类型的真的被普遍接受吗?为什么?
不 - 我不认为它被接受。C++ 具有合理的强类型,并且它一直以来造成麻烦的宽松方式已被修剪掉,例如从其他指针类型的隐式强制转换,以及使用强制转换运算符和构造函数void*
进行更细粒度的控制。explicit
好吧,既然 C++ 的创建者 Bjarne Stroustrup 在The C++ Programming Language(第 4 版)中说该语言是强类型的,我相信他的话:
C++ 编程基于强静态类型检查,大多数技术旨在实现高级抽象和程序员思想的直接表示。与较低级别的技术相比,这通常可以在不影响运行时间和空间效率的情况下完成。为了获得 C++ 的好处,从不同语言接触到它的程序员必须学习并内化惯用的 C++ 编程风格和技术。这同样适用于习惯于 C++ 较早和较少表达版本的程序员。
在 1994 年的这个视频讲座中,他还表示 C 的弱类型系统确实困扰着他,这就是他将 C++ 设为强类型的原因:C++ 的设计,Bjarne Stroustrup 的讲座
让我给你一个简单的例子:
if ( a + b )
C/C+= 允许从 float 到 int 到 Boolean 的隐式转换。
强类型语言不允许这种隐式转换。