什么是「;键入模型“;? 在java(第2.2.9节)中,Brutt TATE声称C++的“类型化”是C++的问题之一。这意味着什么?

什么是「;键入模型“;? 在java(第2.2.9节)中,Brutt TATE声称C++的“类型化”是C++的问题之一。这意味着什么?,java,c++,types,type-theory,Java,C++,Types,Type Theory,,C++代码很难编写。p 但是,他们可能是指C++有一个弱的静态类型系统,这是很容易规避的。一些例子:typedef不是实类型,枚举类型只是int,boolean和integer在许多情况下是等价的,等等

,C++代码很难编写。p


但是,他们可能是指C++有一个弱的静态类型系统,这是很容易规避的。一些例子:typedef不是实类型,枚举类型只是int,boolean和integer在许多情况下是等价的,等等
struct Dog {
    char* name;
    int breed;
};

Dog ralph("Ralph", POODLE);
事实上,
ralph
没有类型;它只是一堆位,CPU根本不在乎你把这些位的集合称为
。例如,以下内容是有效的:

struct Cat {
    int color;
    char* country_of_origin;
};

Cat ralph_is_that_you = * (Cat*) &ralph;
惊奇地看着C教授在
Dog
s和
Cat
s之间进行跨物种突变!这里的要点是,既然
ralph
只是一个位序列,你可以宣称这个位序列实际上是一个
Cat
,没有什么会出错。。。除了“
Cat
”的颜色可能是一些随机的大整数,您最好不要尝试读取它的原产国。基本问题是,虽然变量(如名称,而不是它所代表的对象)具有类型,但基础对象不具有类型

与JAVA相比,JAVA不仅具有类型,而且对象具有内在类型。这可能部分是因为没有指针,因此无法访问内存,但事实仍然存在,如果您将
投射到
对象
,则无法将其投射回
,因为该对象在内心深处知道,它实际上是
,而不是

<> C++中的弱类型是相当有害的,因为它会使编译器静态类型检查几乎无效,如果您想真正滥用证明您的应用程序,也使安全和稳健的软件难以编写。例如,无论何时访问“指针”,都需要非常小心,因为它实际上可能是任何随机位模式

编辑1:评论有非常好的观点,我想在这里添加它们。

指出Sun的JAVA确实有指针,如果你看得足够深入的话。谢谢我不知道,这很酷。然而,最基本的一点是JAVA对象是类型化的,而C类型不是。是的,您可以绕过这一点,但这与opt-in和opt-out垃圾邮件之间的区别是一样的:是的,您可以滥用JAVA指针,但默认情况是不可能滥用。你必须选择加入

指出我展示的例子是一个纯C现象。这是真的,但是

  • C++主要将C作为一个子集来包含(差别通常很小,无法列出)
  • C++包括
    重新解释cast
    ,专门允许这样的黑客攻击
  • 仅仅因为它被劝阻并不意味着它不是普遍的或危险的。基本上,即使JAVA有opt-in指针(我称之为opt-in指针),事实上使用它们的人可能已经考虑到了后果。C的强制转换非常简单,有时不用思考就可以完成(引用Stroustroup的话,“但是新的语法故意变得丑陋,因为强制转换仍然是一个丑陋且常常不安全的操作。”)。还有一个事实,绕过java的类型系统所需要的工作远比一个聪明的黑客所能做的要多,而绕过C型系统(和,是的C++类型系统)是很容易的,我看到它只是为了一个小的性能提升而做的。
  • 不管怎样,阻止某些事情并不能使它不发生。我不鼓励糟糕的编码,但我还没有看到它让我有任何进展


    至于功能是否有用,这是无可否认的(只需在谷歌或维基百科上查找“快速平方根反比”),但按照Stroustroup的格言“丑陋的操作应该是丑陋的”,难度阈值应该要高得多。你的观点很有道理。但C++由于其严格的静态分型系统而优于C。您所说的是类型之间的自动转换(不幸的是,它是从C继承的)。还要注意:两个不同枚举之间的转换无效(虽然不幸的是它自动转换为int)。C++显示了为什么C不是严格类型的。你使用的是C投A,虽然它可以从C++中使用,但它仍然被认为是C构造,它的使用比C++的C++更令人沮丧。诚然,它很容易被滥用,但这并不会使编写健壮或安全的软件变得更加困难。因为C++严格的静态类型指针通常不是随机指针(它们可能是因为使用了C转换的滥用,或者是在没有使用的好代码中的),java(Sun的IMPL)确实有指针。请参阅sun.misc.Unsafe上的javadocs。特别是getAddress(长地址)和putAddress(长地址,长x)。是的,您必须使用反射来访问不安全的,是的,它是不可移植的,但是我们这里讨论的是故意滥用,对吗?呃,也不可能滥用C指针。你所做的是未定义的行为。它不再是一个C程序。C程序由C标准描述。未定义的行为不是。如果你不尊重语言规则,那么是的,你可以写一些纯粹的废话。但这并不是因为语言有任何缺陷。那是因为你不知道你正在使用的语言。一点也不正确。首先,假设所有编译器在发生这种滥用时都做同样的事情,你几乎不能认为它是未定义的。例如,考虑HTML。无效标记的效果尚未定义,但仍然会发生无效标记。不管怎样,它基本上是有效的。此外,
    void*
    指针的存在是标准的一部分,它们是