【问题标题】:Is C++ considered weakly typed? Why?C++ 被认为是弱类型的吗?为什么?
【发布时间】:2015-01-01 10:12:51
【问题描述】:

我一直认为 C++ 是目前最强类型的语言之一。
所以我很震惊看到Table 3 of this paper声明C++是弱类型的。

显然,

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

类型转换的存在是否重要?这种类型转换的显式是否无关紧要?

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

【问题讨论】:

  • C++ 不是弱类型的,但如果你愿意,你可以颠覆类型系统。所以有人可能会说它不是完全强类型的。
  • .. 如果它允许你(类型双关语很棘手)
  • @Mehrdad 我认为“弱类型”是一个非常主观的术语。 “严格类型”和“静态类型”与“松散类型”和“动态类型”是更客观、更精确的词。据我所知,通常人们使用“弱类型”作为贬义词,意思是“我不喜欢这种语言中的类型概念”。对于那些无法针对特定语言提出专业技术论据的人来说,这有点像是一种自言自语(或者更确切地说,自称自述语言 linguam)。
  • @Mehrdad 的解释也略有不同;普遍接受的意思是“如果类型不匹配,编译器会产生错误”。另一种解释是“没有或很少有隐式转换”。基于此,C++ 实际上可以被认为是一种严格类型的语言,并且大多数情况下它被认为是。
  • Bjarne Stroustrup 的书在第 2 页提到 C++ 是一种强类型语言。谁会比他更了解 :-)

标签: c++ strong-typing reinterpret-cast weak-typing


【解决方案1】:

那篇论文首先声称:

相反,如果类型混淆可以静默发生(未被检测到)并最终导致难以本地化的错误,则该语言是弱类型语言。

然后声明:

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

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

也就是说,根据论文中的定义,C 和 C++可能仍被视为弱类型。正如已经在问题上的 cmets 中指出的那样,存在语言支持隐式类型转换的情况。许多类型可以隐式转换为bool,int 类型的字面零可以静默转换为任何指针类型,不同大小的整数之间存在转换等,所以这似乎是考虑 C 和出于本文的目的,C++ 是弱类型的。

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

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

就本文而言,这绝对是弱类型。位的重新解释是静默发生的,并且可以通过将其修改为使用完全不相关的类型而变得更糟,这些类型具有静默的未定义行为,通常与重新解释位具有相同的效果,但在启用优化时会以神秘但有时有趣的方式爆炸.

不过,总的来说,我认为“强类型”和“弱类型”没有固定的定义。有各种等级,与汇编相比是强类型的语言可能与 Pascal 相比是弱类型的。要确定 C 或 C++ 是否属于弱类型,您首先必须询问您想要弱类型的含义。

【讨论】:

  • +1 好点。但要回答这个问题,您还应该提及 C++ 是否被接受的定义强类型化!
  • @Mehrdad 同意,并扩展了我的答案。
  • @AndreyChernyakhovskiy 不,他们不能。 “Cast”表示“显式转换”(或者具体来说,用于编写显式转换的语法)。有隐式转换,就像我在回答中已经指出的那样,但它们不称为强制转换。
  • @AndreyChernyakhovskiy:不安全的转换不会在 C++ 中隐式发生,但在 C 中会发生(例如指针转换)。
  • @Mehrdad 啊,是的,我认为您可能有一个很好的观点。我应该将其添加到我的答案中。
【解决方案2】:

“弱类型” 是一个相当主观的术语。我更喜欢术语“严格类型”和“静态类型”而不是“松散类型”和“动态类型”, 因为它们是更客观、更准确的词。

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

术语“严格类型”的解释也略有不同;根据我的经验,普遍接受的含义是“如果类型不匹配,编译器会生成错误”。另一种解释是“没有或很少有隐式转换”。 基于此,C++ 实际上可以被认为是一种严格类型的语言,而且大多数情况下也被认为是这样的。我想说的是,对 C++ 的普遍共识是它是一种严格类型的语言。

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

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

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

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

【讨论】:

    【解决方案3】:

    相反,如果类型混淆可以静默发生(未被检测到)并最终导致难以本地化的错误,则该语言是弱类型语言。

    嗯,这可以在 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 转换运算符和构造函数进行更细粒度的控制.

    【讨论】:

      【解决方案4】:

      我举个简单的例子:

       if ( a + b )
      

      C/C+= 允许从 float 到 int 到 Boolean 的隐式转换。

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

      【讨论】:

        【解决方案5】:

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

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

        在 1994 年的这个视频讲座中,他还表示 C 的弱类型系统确实困扰着他,这就是他将 C++ 设为强类型的原因:The Design of C++ , lecture by Bjarne Stroustrup

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-05
          • 2014-11-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多