我一直认为C ++是最强类型的语言之一。
因此,当看到本文第3表格指出C ++是弱类型时,我感到非常震惊。
显然,
由于类型转换,C和C ++被认为是弱类型,因为可以将结构体字段解释为整数指针。
是否只存在类型转换?这些显式转换的明确性是否不重要?
更普遍地说,C ++真的被普遍认为是弱类型吗?为什么?
我一直认为C ++是最强类型的语言之一。
因此,当看到本文第3表格指出C ++是弱类型时,我感到非常震惊。
显然,
由于类型转换,C和C ++被认为是弱类型,因为可以将结构体字段解释为整数指针。
是否只存在类型转换?这些显式转换的明确性是否不重要?
更普遍地说,C ++真的被普遍认为是弱类型吗?为什么?
这篇论文首先声明:
相反,如果类型混淆可以悄无声息(未被检测到)地发生,并最终导致难以定位的错误,则语言是弱类型的。
然后它声明:
C和C++也被认为是弱类型的,因为由于类型转换,可以将结构的字段解释为整数而不是指针。
对我来说,这似乎是一种矛盾。在C和C++中,由于有类型转换,因此可能会发生的类型混淆不会悄无声息发生!这并没有证明这两种语言是弱类型的,至少根据那篇论文的定义。
也就是说,根据该论文的定义,C和C++仍然可能被认为是弱类型的。正如已经在问题评论中指出的那样,语言支持隐式类型转换的情况很多。许多类型可以隐式转换为bool
,类型为int
的字面零可以悄无声息地转换为任何指针类型,存在不同大小的整数之间的转换等。因此,这似乎是将C和C++视为弱类型的一个很好的理由。
int main() {
int i = 0;
void *v = &i;
char *c = v;
return *c;
}
就本文而言,这必须被视为弱类型。位的重新解释是默默发生的,并且通过修改它以使用完全不相关的类型,可以使其变得更糟,这具有静默未定义行为,通常具有重新解释位的相同效果,但在启用优化时会以神秘但有时令人愉快的方式爆炸。
总的来说,我认为“强类型”和“弱类型”没有固定的定义。有各种等级,与汇编相比较强类型的语言可能与Pascal相比较弱类型。要确定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
}
这个主题存在一些混淆。有些术语会因书籍而异(不考虑互联网),有些可能随着时间的推移而改变。
以下是我从书籍“编译器工程”(第二版)中理解的内容。
完全没有类型的语言,例如汇编语言。
具有较差的类型系统的语言。 此处的定义是故意模糊的。
每个表达式都具有明确的类型的语言。PL可以进一步分类为:
嗯,它肯定是强类型的。大多数情况下它是静态类型的。 但由于一些表达式只能在运行时分配类型,我想它属于3.B类别。
一个强类型的语言,可以进行静态检查,但由于某些原因可能只使用运行时检查实现。
我没有拥有它,所以不知道在这方面是否有任何改变。 但总的来说,“语义分析”章节的标题和目录顺序都发生了变化。
让我给你举个简单的例子:
if ( a + b )
C/C++ 允许从 float 到 int 再到 Boolean 的隐式转换。
强类型语言不允许这种隐式转换。