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

时间:2014-11-05 09:23:43

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

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

显然,

  

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

类型铸造的存在是否重要?这种演员的明确性是否无关紧要?

更一般地说,人们普遍认为C ++是弱类型的吗?为什么呢?

5 个答案:

答案 0 :(得分:22)

该论文首先声称:

  

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

然后声称:

  

此外,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 ++是否为弱类型,首先要问你想要弱类型的意思。

答案 1 :(得分:6)

“弱类型”是一个非常主观的术语。我更喜欢术语“严格打字”“静态打字”“松散打字”“动态打字”,< / strong>因为它们更客观,更准确。

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

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

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

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

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

总结一下:可能没有语言完全完全到一个或另一个类别,但我们可以说某个特定语言的哪个特定属性占主导地位。 在C ++中,严格性确实占主导地位。

答案 2 :(得分:2)

  

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

嗯,这可能发生在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 ++允许在类型之间进行显式转换,但这几乎不会“弱”。 - 根据网站自己的定义,它不会意外/无声地发生。

  

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

明确是恕我直言的重要考虑因素。让程序员覆盖编译器的类型知识是&#34; power&#34; C ++的功能,而不是一些弱点。它不容易被意外使用。

  

更一般地说,人们普遍认为C ++是弱类型的吗?为什么呢?

不 - 我不认为它被接受了。 C ++的类型是相当强的类型,并且它已经在历史上造成麻烦的宽松方式被修剪回来了,例如从void*到其他指针类型的隐式转换,以及explicit的更精细控制铸造操作员和施工人员。

答案 3 :(得分:0)

好吧,自从C ++的创建者Bjarne Stroustrup在《 C ++编程语言》(第4版)中说,该语言是强类型化的,所以我相信他的话:

  

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

在1994年的这段视频演讲中,他还指出C的弱类型系统确实困扰着他,这就是为什么他使C ++强类型化: The Design of C++ , lecture by Bjarne Stroustrup

答案 4 :(得分:-3)

让我举个简单的例子:

 if ( a + b )

C / C + =允许从float到int的隐式转换为布尔值。

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