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

lf3rwulv  于 2022-11-27  发布在  其他
关注(0)|答案(6)|浏览(407)

我一直认为C是最强类型的语言之一。
因此,当我看到Table 3 of this paper声明C
是弱类型的时,我非常震惊。
很显然,
C和C被认为是弱类型的,因为由于类型转换,人们可以将结构中的整数字段解释为指针。
类型转换的存在是唯一重要的吗?类型转换的明确性不重要吗?
更一般地说,C
是弱类型的,这真的被普遍接受了吗?为什么?

ikfrs5lh

ikfrs5lh1#

一般情况下:

围绕这个主题有一种混乱。有些术语因书而异(这里不考虑互联网),有些可能这些年来已经改变了。
下面是我从《编译器工程》(第二版)一书中了解到的。

1.无类型语言

完全没有类型的语言,例如汇编语言。

2.弱类型语言:

类型系统不佳的语言。这里的定义是故意模棱两可的。

3.强类型语言:

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

*A.静态类型化:每个表达式在编译时都被赋值一个类型时。
*B.动态类型化:某些表达式只能在运行时类型化时。

那么C++是什么?

当然,它是强类型的。而且大多数情况下它是静态类型的。但是由于一些表达式只能在运行时才能被类型化,我猜它福尔斯3.B类别。
PS1:书中的注解:
一个可以静态检查的强类型语言,可能(出于某种原因)只通过运行时检查来实现。

PS2:第三版最近发布

我不拥有它,所以我不知道在这方面有没有什么变化。但总的来说,“语义分析”一章的标题和目录顺序都有变化。

waxmsbnn

waxmsbnn2#

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

if ( a + b )

C/C+=允许从float到int再到Boolean的隐式转换。
强类型语言不允许这样的隐式转换。

mo49yndu

mo49yndu3#

那篇论文首先宣称:
相反,如果类型混淆可以悄悄地发生(未检测到),并最终导致难以本地化的错误,则一种语言是弱类型的。
然后主张:
此外,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++是弱类型的,你首先要问你想要弱类型是什么意思。

tyky79it

tyky79it4#

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

据我所知,人们通常使用“弱类型”作为一个小型的贬义词,意思是“我不喜欢这种语言中的类型概念”。这是一种针对个人的论证(或者更确切地说,argumentum ad linguam),针对那些不能提出专业或技术论点来反对某一特定语言的人。
术语“严格类型化”也有稍微不同的解释;根据我的经验,通常接受的含义是“如果类型不匹配,编译器将生成错误”。另一种解释是“没有隐式转换或隐式转换很少”。基于此,C实际上可以被认为是一种严格类型化的语言,而且大多数情况下也是如此。**我想说,关于C的普遍共识是,它一种严格类型化的语言。
当然,我们可以尝试一种更微妙的方法来解决这个问题,说语言的一部分是严格类型化的(这是大多数情况),其他部分是松散类型化的(一些隐式转换,例如算术转换和四种显式转换)。
此外,还有一些程序员,尤其是不熟悉几种语言的初学者,他们不打算或不能区分“严格”和“静态”、“松散”和“动态”,并根据他们有限的经验(例如,通常是流行的脚本语言中动态和松散类型的相关性)将这两个原本相互正交的概念混为一谈。
实际上,C的部分(虚拟调用)要求类型系统是部分动态的,但标准中的其他东西要求它是严格的。同样,这不是一个问题,因为这些是正交的概念。
总而言之:可能没有一种语言能够 * 完全、完美地 * 归入某个类别,但我们可以说一种给定语言的哪种特定属性占主导地位。**在C
中,严格性绝对占主导地位。

jhkqcmku

jhkqcmku5#

相反,如果类型混淆可以悄悄地发生(未检测到),并最终导致难以本地化的错误,则一种语言是弱类型的。
这在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被认为是弱类型的,因为由于类型转换,人们可以将结构中的整数字段解释为指针。
Ummmm...不是通过任何隐式转换,所以这是一个愚蠢的论点。C
允许类型之间的显式转换,但这并不“弱”--它不会像上面网站自己的定义所要求的那样意外地/悄悄地发生。
类型转换的存在是唯一重要的吗?类型转换的明确性不重要吗?
恕我直言,显式性是一个至关重要的考虑因素。让程序员覆盖编译器的类型知识是C的“强大”特性之一,而不是什么弱点。它不容易被意外使用。
更一般地说,C
是弱类型的,这真的被普遍接受了吗?为什么?
C++是相当强的类型化语言,过去曾造成麻烦的宽松方式已经被删除,例如从void*到其他指针类型的隐式转换,以及使用explicit转换操作符和构造函数的更细粒度的控制。

yfwxisqw

yfwxisqw6#

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

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

在1994年的视频讲座中,他还说C的弱类型系统确实困扰着他,这就是为什么他把C++变成强类型的:******

相关问题