5
program TypeCategory;
{$R+}
var
    sInt : shortint;
    iInt : integer;
begin
    readln(iInt);
    sInt := iInt;
    writeln(sInt);
end.

上記の例を考慮すると、パスカル言語は to からの代入、または明示的な型キャストなしで to への代入をinteger許可shortintlongintますshortint

Pascal はそのことで有名ですがstrongly typed、なぜこのようなことが許されるのweakly typedでしょうか?この種の構文は一貫性のないコードを助長すると思います。

この種の構文の長所は何ですか?有名な C と C++ を除いて、この種の構文を適用した他の言語はありますか?

ありがとう。

編集
私はテストturbo pascalしただけfree pascal with fpc/objfpc/tp/delphi modelで、また、同じ結果gcc/g++を生成します。つまり、 (私のコンピューターでは4バイトのサイズ)から(2のサイズ)への割り当ては、コンパイルエラーをトリガーしませんが、設定できますコンパイラに警告を生成させる適切なオプション。msvcintshort intpossible lose of data

4

5 に答える 5

8

パート 1. 定義について

まず第一に、「パスカル」と呼ぶ言語と実装は何ですか? ISO Pascalについて話している場合、それは何年も前に死んでいます。他の言語または実装について話している場合は、より多くの情報を提供してください。

次に (Teun D が既に述べたように) 強い型付けという用語の定義はありません強い型付けに関するウィキペディアの記事をご覧ください。

ただし、これらの用語には、コンピューティングの短い歴史の中で非常にさまざまな意味が与えられているため、個々の作成者がそれらを使用するときに何を意味するかを文脈から切り離して知ることはしばしば困難です。

ウィキペディアのページで以下に説明されている Luca Cardelli の記事 Typeful Programming の定義に従うと仮定しましょう。

Luca Cardelli の記事 Typeful Programming では、強力な型付けとは、チェックされていない実行時の型エラーがないことと単純に説明しています。別の記述では、チェックされていない実行時エラーがないことは、安全性または型安全性と呼ばれます。Tony Hoare の初期の論文では、これを資産セキュリティと呼んでいます。

とにかく、説明されている動作は、静的 (または安全な) タイピングの規律として分類することはできません。私は個人的にこれが本当に嫌いです...うーん、それは機能ではなく、バグです。=)

パート 2. 回答

問題はこの弱い型付けではなく、一部の言語で利用可能な多種多様な整数型にあると思います。

有名な C と C++ を除いて、この種の構文を適用した他の言語はありますか?

さまざまな整数型を持つほとんどすべての静的型付け言語には、このような動作があると思います。メモリ節約のために、この SHORTINT とすべてのジャズを早い段階で使用することをお勧めします。しかし今では、ほぼすべての PC が約 1 GB 以上の RAM を備えているため、2 バイトの SHORTINT ではなく 4 バイトの INTEGER が 100 万個あるとします。2 MB ではなく、約 4 MB の RAM しかありません。あなたが説明したこの奇妙な動作がすべてないのは、妥当な価格だと思います。

Wirth の Oberon-07 (言語レポート、PDF ) を簡単に見てみましょう。整数型は 32 ビット INTEGER の 1 つだけです。

また、使用可能な (仮想) メモリのみを条件として、無制限の範囲の数値を表す int 型を持つ Python (または他の最新の動的型付け言語) について言及することもできます。

ですから、傾向を見ることができます - さまざまな整数型は 70 年代のサバイバルです。=)

この種の構文の長所は何ですか?

長所は、(おそらく) 冗長性の削減です。この静的に型付けされた言語はすでに非常に冗長であるため、Wirth が Oberon-2 で行ったような明示的な整数型変換を追加すると決定すると (SHORT() および LONG() 関数を見てください)、さらに冗長になります。妥協案として、暗黙の変換を許可することができます。また、多くの言語では、整数型変数の実際のサイズは固定されておらず、実装ごとに異なります。利用可能な唯一の情報は、size(shortint) <= size(int) です。等式の場合、明示的な変換は非常に奇妙に見えます。

パート 3. Dithyramb から Oberon-2 へ =)

ところで、Pascal についてはあまり警戒しないでください。死んでしまいましたが、Oberon-2でNiklaus Wirth が間違いを修正しました。

言語レポートの第 6 章では、型に関する情報を見つけることができます。私たちの議論にとって重要な声明は次のとおりです。

型 3 から 5 は整数型、型 6 と 7 は実数型で、これらを合わせて数値型と呼びます。それらは階層を形成します。大きい方の型には小さい方の型 (の値) が含まれます: LONGREAL >= REAL >= LONGINT >= INTEGER >= SHORTINT

9 章では、割り当てについて読むことができます。

式は、変数と互換性のある代入でなければなりません

最後に付録 A:

課題対応

次の条件のいずれかが成り立つ場合、Te 型の式 e は、Tv 型の変数 v と代入互換性があります。

Te と Tv は同じ型です。

Te と Tv は数値型で、Tv には Te が含まれます。

...

ここにいます。INTEGER 式を SHORTINT 変数に代入することはできません。興味がある場合は、Oberon-2 のマイナー バリアントおよび改良版であるComponent Pascalも参照してください。BlackBox Component Builderは、Windows 用の IDE です。


ジャスティン・スミスのコメントに応えて。

「REAL」として表現できない LONGINTS があることを考えると、LONGREAL >= REAL >= LONGINT >= INTEGER >= SHORTINT という大きな型には小さな型 (の値) が含まれていると彼が言ったことに驚いています。

私はあなたの発言について少し混乱しています

「REAL」で表現できないLONGINTがあります

実際に私のマシンでは、上記のIDEが

MAX(倍長整数) = 9223372036854775807

最大 (実数) = 1.797693134862316E+308

したがって、すべての LONGINT を REAL 数として表すことができます。しかし、表現は正確ではないかもしれません。あなたは実際にそれについて話していたと思いますが、ここではさまざまな整数型の変換について話しています。また、REAL と INTEGER の間の変換は別の話です。悪くて紛らわしいネーミングの話。REAL 数は、数学的な観点からは実際には実数ではありません。それらはおおよその表現です。有理数近似 (分子と分母を整数として格納する)を使用できますが、一般的な方法は浮動小数点近似を使用することです。浮動小数点演算の IEEE 規格(IEEE 754 とも呼ばれます) は、浮動小数点計算で最も広く使用されている規格です。

REAL 数値は実数ではなく、IEEE 754 標準で記述された数値であることを誰もが知っておく必要があります。そして、誰もが「すべてのコンピュータ科学者が浮動小数点演算について知っておくべきこと」を読んで、いくつかの点を明確にする必要があります。

しかし、それは別の話です... =)

于 2010-01-22T20:20:07.400 に答える
2

使用する言語に関係なく、プログラマーが自分自身を撃つ方法は常にあります。変数を使用するときは、格納するデータの種類とその使用方法を認識する必要があります。強力な型付けによりこれはより安全になりますが、大きな変数から小さな変数に誤ってキャストする可能性があります。

于 2010-01-22T20:25:22.170 に答える
0

int から short int への代入が言語で許可されていない場合、このコードを記述することは不可能です。

var
sInt : shortint;
iInt : integer;

if (iInt < 100 && iInt > -100)
{
   sInt := iInt; // this would not compile
}

またはこれ

var
sInt : shortint;
iInt : integer;

sInt := (iInt & 0xFFFF); // this would not compile

このように、短い int で計算を行っているときに、int を一時的な値として使用するコードを書くことはできませんでした。

var
sInt1 : shortint;
sInt2 : shortint;
iInt : integer;

/* I want to multiply sInt2 by sInt1 and then divide by 100 */
iInt = sInt2;
sInt2 := (iInt * sInt1) / 100; // this would not compile

ただし、一時値のオーバーフローによるエラーが発生しないようにするには、一時値により多くのビットを使用するのが一般的な手法です。

于 2010-01-27T00:41:27.300 に答える
0

shortintこの動作は、実際には を指しているへのポインターを取得できないという意味で、弱い型付けではないと思いますinteger。また、クラッシュが発生することもありません (ただし、2 番目の変数の数値は予想と異なる場合があります)。

つまり、明らかに、Pascal はオーバーフローをチェックしないということです。例えば。C# では、コード ( http://msdn.microsoft.com/en-us/library/khy08726(VS.71).aspx )からチェック動作を設定できますが、多くの場合、これはパフォーマンスを考慮して行われません。これはパスカルにも当てはまると思います。

于 2010-01-17T16:36:21.327 に答える