C++被认为是弱类型的吗?为什么?
Is C++ considered weakly typed? Why?
我一直认为C++是最强类型的语言之一
因此,看到本文的表3指出C++是弱类型的,我非常震惊。
显然,
C和C++被认为是弱类型的,因为由于类型转换,可以将整数结构的字段解释为指针。
类型铸造的存在才是最重要的吗?这种演员阵容的明确性无关紧要吗?
更普遍地说,C++是弱类型的,这真的被普遍接受吗?为什么?
该论文首次声称:
相反,如果类型混淆可能会悄无声息地发生(未被检测到),并最终导致难以本地化的错误,那么语言就是弱类型的。
然后声称:
此外,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;
}
就本文的目的而言,这肯定被认为是弱类型的。比特的重新解释是无声的,如果将其修改为使用完全不相关的类型,情况可能会变得更糟,这种类型具有无声的未定义行为,通常与重新解释比特具有相同的效果,但当启用优化时,会以神秘但有时很有趣的方式爆发。
不过,总的来说,我认为"强类型"answers"弱类型"并没有固定的定义。有不同的等级,与汇编相比是强类型的语言与Pascal相比可能是弱类型的。要确定C或C++是弱类型的,首先必须询问弱类型是什么意思。
"弱类型"是一个相当主观的术语。我更喜欢术语"严格类型"answers"静态类型"而不是"松散类型"
据我所知,人们通常使用"弱类型"作为一个小型贬义词,意思是"我不喜欢这种语言中的类型概念"。对于那些不能提出反对特定语言的专业或技术论点的人来说,这有点像人的论点(或者更确切地说,语言的论点)。
"严格打字"一词也有稍微不同的解释;根据我的经验,公认的含义是"如果类型不匹配,编译器会生成错误"。另一种解释是"没有或很少有隐含的转换"基于此,C++实际上可以被认为是一种严格类型的语言,而且通常被认为是这样的我想说,关于C++的普遍共识是,它是一种严格类型的语言。
当然,我们可以尝试一种更微妙的方法来解决这个问题,并说语言的部分是严格类型的(这是大多数情况),其他部分是松散类型的(一些隐式转换,例如算术转换和四种显式转换)。
此外,还有一些程序员,尤其是不熟悉几种语言的初学者,他们不打算或不能区分"严格"answers"静态"、"松散"answers"动态",并根据它们有限的经验(例如,流行脚本语言中动态性和松散类型的相关性)将这两个原本正交的概念混为一谈。
事实上,C++(虚拟调用)的某些部分要求类型系统是部分动态的,但标准中的其他内容要求它是严格的。同样,这不是问题,因为这些都是正交概念。
总之:可能没有一种语言能完全、完美地归入一个或另一个类别,但我们可以说给定语言的哪个特定属性占主导地位在C++中,严格确实占主导地位
好吧,既然C++的创建者Bjarne Stroustrup在《C++编程语言》(第4版)中说这种语言是强类型的,我相信他的话:
C++编程基于强静态类型检查,大多数技术旨在实现高级抽象和程序员思想的直接表示。与较低级别的技术相比,这通常可以在不影响运行时间和空间效率的情况下完成。为了获得C++的好处,来自不同语言的程序员必须学习并内化惯用的C++编程风格和技术。这同样适用于习惯于早期和表达能力较差的C++版本的程序员。
在1994年的这场视频讲座中,他还表示,C的弱类型系统真的让他很困扰,这就是他让C++成为强类型的原因:C++的设计,由Bjarne Stroustrup教授
相反,如果类型混淆可能会悄无声息地发生(未被检测到),并最终导致难以本地化的错误,那么语言就是弱类型的。
好吧,这可能发生在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++允许类型之间的显式转换,但这并不"弱"——它不会像上面网站自己的定义所要求的那样意外/静默地发生。
类型铸造的存在才是最重要的吗?这种演员阵容的明确性无关紧要吗?
明确性是IMHO的一个重要考虑因素。让程序员重写编译器的类型知识是C++的"强大"功能之一,而不是一些弱点。它不容易被意外使用。
更普遍地说,C++是弱类型的,这真的被普遍接受吗?为什么?
不,我不认为这是可以接受的。C++是相当强的类型,并且它在历史上造成麻烦的宽松方式已经被修剪掉,例如从void*
到其他指针类型的隐式强制转换,以及使用explicit
强制转换运算符和构造函数的细粒度控制。
概述:
围绕这个主题有一种混乱。有些术语因书而异(这里不考虑互联网),有些术语可能多年来发生了变化。
以下是我从这本书";工程编译器";(第2版)。
1.未键入的语言
完全没有类型的语言,例如程序集中的语言。
2.弱类型语言:
具有较差类型系统的语言。这里的定义故意模棱两可。
3.强类型语言:
每个表达式都有明确类型的语言。PL可进一步分类为:
- A。静态类型化:编译时为每个表达式分配一个类型时
- B。动态类型化:当某些表达式只能在运行时键入
那么什么是C++
当然,它是强类型的。而且大部分是静态类型的。但是,由于某些表达式只能在运行时键入,我想它属于3.B类别。
PS1:书中的一条注释:
可以静态检查的强类型语言(出于某种原因)可能只通过运行时检查来实现。
PS2:第三版最近发布
我不拥有它,所以我不知道在这方面是否有什么变化。但一般来说;语义分析";第章更改了目录中的标题和顺序。
让我给你一个简单的例子:
if ( a + b )
C/C++允许从浮点到int到布尔的隐式转换。
强类型语言不允许这样的隐式转换。
- 使用简单类型列表实现的指数编译时间.为什么
- 为什么与常规GCC不同,即使有"学究性错误",MinGW-GCC也能容忍丢失的返回类型
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 为什么类型 char 返回不同的值?
- 为什么类型铸件仅在这句话中失败
- 为什么类型变量;不调用默认 CTR
- 为什么类型转换对象不会更改其地址?有关对象类型的信息存储在哪里?
- 为什么类型关键字以"_t"后缀结尾?
- 为什么类型特征不适用于命名空间范围内的类型?
- 为什么类型可转换性C++不传递
- 为什么 T& 类型的模板函数参数可以绑定到常量左值而不是右值?
- 为什么类型为 sf::Text 的对象返回不同的 getPosition().y 和 getLocalBounds().
- 为什么类型扣除会失败(非销售)功能类型
- 为什么C类型泛型表达式不能与C++兼容
- 为什么类型是char
- 为什么C++类型的表达式没有从左到右进行解释
- 为什么类型长赋值中的文本值在 C++ 的末尾仍然有一个'L'?
- 为什么类型转换运算符不适用于继承的类?
- 为什么类型推导不能按预期工作
- 为什么类型知识在Boost::MPL中消失了?