我一直认为C ++是最强类型的语言之一 所以我非常感到震惊看到Table 3 of this paper声明C ++是弱类型的。
显然,
C和C ++被认为是弱类型的,因为由于类型转换,人们可以将结构的字段解释为整数作为指针。
类型铸造的存在是否重要?这种演员的明确性是否无关紧要?
更一般地说,人们普遍认为C ++是弱类型的吗?为什么呢?
答案 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的隐式转换为布尔值。
强类型语言不允许这种隐式转换。