C++被认为是弱类型的吗?为什么?

Is C++ considered weakly typed? Why?

本文关键字:为什么 类型 认为是 C++      更新时间:2023-10-16

我一直认为C++是最强类型的语言之一
因此,看到本文的表3指出C++是弱类型的,我非常震惊。

显然,

C和C++被认为是弱类型的,因为由于类型转换,可以将整数结构的字段解释为指针。

类型铸造的存在才是最重要的吗?这种演员阵容的明确性无关紧要吗?

更普遍地说,C++是弱类型的,这真的被普遍接受吗?为什么?

该论文首次声称:

相反,如果类型混淆可能会悄无声息地发生(未被检测到),并最终导致难以本地化的错误,那么语言就是弱类型的。

然后声称:

此外,C和C++被认为是弱类型的,因为由于类型转换,可以将整数结构的字段解释为指针。

这对我来说似乎是一个矛盾。在C和C++中,由于强制类型转换而可能发生的类型混淆不会悄无声息地发生——有强制类型转换!这并不能证明这两种语言中的任何一种都是弱类型的,至少根据论文中的定义是这样。

也就是说,根据本文中的定义,C和C++仍然可以被认为是弱类型的。正如在对该问题的评论中已经指出的那样,在某些情况下,该语言支持隐式类型转换。许多类型可以隐式转换为boolint类型的文字零可以静默地转换为任何指针类型,不同大小的整数之间也有转换,等等,所以这似乎是考虑C和C++弱类型的一个很好的理由。

对于C(但不是C++),还有更危险的隐式转换值得一提:

int main() {
  int i = 0;
  void *v = &i;
  char *c = v;
  return *c;
}

就本文的目的而言,这肯定被认为是弱类型的。比特的重新解释是无声的,如果将其修改为使用完全不相关的类型,情况可能会变得更糟,这种类型具有无声的未定义行为,通常与重新解释比特具有相同的效果,但当启用优化时,会以神秘但有时很有趣的方式爆发。

不过,总的来说,我认为"强类型"answers"弱类型"并没有固定的定义。有不同的等级,与汇编相比是强类型的语言与Pascal相比可能是弱类型的。要确定C或C++是弱类型的,首先必须询问弱类型是什么意思。

"弱类型"是一个相当主观的术语。我更喜欢术语"严格类型"answers"静态类型"而不是"松散类型"

据我所知,人们通常使用"弱类型"作为一个小型贬义词,意思是"我不喜欢这种语言中的类型概念"。对于那些不能提出反对特定语言的专业或技术论点的人来说,这有点像人的论点(或者更确切地说,语言的论点)。

"严格打字"一词也有稍微不同的解释;根据我的经验,公认的含义是"如果类型不匹配,编译器会生成错误"。另一种解释是"没有或很少有隐含的转换"基于此,C++实际上可以被认为是一种严格类型的语言,而且通常被认为是这样的我想说,关于C++的普遍共识是,它是一种严格类型的语言。

当然,我们可以尝试一种更微妙的方法来解决这个问题,并说语言的部分是严格类型的(这是大多数情况),其他部分是松散类型的(一些隐式转换,例如算术转换和四种显式转换)。

此外,还有一些程序员,尤其是不熟悉几种语言的初学者,他们不打算或不能区分"严格"answers"静态"、"松散"answers"动态",并根据它们有限的经验(例如,流行脚本语言中动态性和松散类型的相关性)将这两个原本正交的概念混为一谈。

事实上,C++(虚拟调用)的某些部分要求类型系统是部分动态的,但标准中的其他内容要求它是严格的。同样,这不是问题,因为这些都是正交概念。

总之:可能没有一种语言能完全、完美地归入一个或另一个类别,但我们可以说给定语言的哪个特定属性占主导地位在C++中,严格确实占主导地位

好吧,既然C++的创建者Bjarne Stroustrup在《C++编程语言》(第4版)中说这种语言是强类型的,我相信他的话:

C++编程基于强静态类型检查,大多数技术旨在实现高级抽象和程序员思想的直接表示。与较低级别的技术相比,这通常可以在不影响运行时间和空间效率的情况下完成。为了获得C++的好处,来自不同语言的程序员必须学习并内化惯用的C++编程风格和技术。这同样适用于习惯于早期和表达能力较差的C++版本的程序员。

在1994年的这场视频讲座中,他还表示,C的弱类型系统真的让他很困扰,这就是他让C++成为强类型的原因:C++的设计,由Bjarne Stroustrup教授

相反,如果类型混淆可能会悄无声息地发生(未被检测到),并最终导致难以本地化的错误,那么语言就是弱类型的。

好吧,这可能发生在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++允许类型之间的显式转换,但这并不"弱"——它不会像上面网站自己的定义所要求的那样意外/静默地发生。

类型铸造的存在才是最重要的吗?这种演员阵容的明确性无关紧要吗?

明确性是IMHO的一个重要考虑因素。让程序员重写编译器的类型知识是C++的"强大"功能之一,而不是一些弱点。它不容易被意外使用。

更普遍地说,C++是弱类型的,这真的被普遍接受吗?为什么?

不,我不认为这是可以接受的。C++是相当强的类型,并且它在历史上造成麻烦的宽松方式已经被修剪掉,例如从void*到其他指针类型的隐式强制转换,以及使用explicit强制转换运算符和构造函数的细粒度控制。

概述:

围绕这个主题有一种混乱。有些术语因书而异(这里不考虑互联网),有些术语可能多年来发生了变化。

以下是我从这本书";工程编译器";(第2版)。


1.未键入的语言

完全没有类型的语言,例如程序集中的语言。


2.弱类型语言:

具有较差类型系统的语言。这里的定义故意模棱两可。


3.强类型语言:

每个表达式都有明确类型的语言。PL可进一步分类为:

  • A。静态类型化:编译时为每个表达式分配一个类型时
  • B。动态类型化:某些表达式只能在运行时键入


那么什么是C++

当然,它是强类型的。而且大部分是静态类型的。但是,由于某些表达式只能在运行时键入,我想它属于3.B类别。

PS1:书中的一条注释:

可以静态检查的强类型语言(出于某种原因)可能只通过运行时检查来实现。

PS2:第三版最近发布

我不拥有它,所以我不知道在这方面是否有什么变化。但一般来说;语义分析";第章更改了目录中的标题和顺序。

让我给你一个简单的例子:

 if ( a + b )

C/C++允许从浮点到int到布尔的隐式转换。

强类型语言不允许这样的隐式转换。