2016-05-10 11 views
-4

私はWindowsプログラムをOS Xに移植する作業を与えられました。もともとC++で書かれていましたが、私はC言語の言語で作業することはしばしばで、Objective C++ポートで。C++開発者は一般的に暗黙的なキャストをカウントしますか?

しかし、Windowsのソースコードは何か変わったことがあり、私はそれが標準的な方法かどうか疑問に思っています。 WindowsとOS Xの両方で動作しているAPIは、特定のオブジェクトメソッドがunsigned shortを渡すことを期待しています。関数がunsigned shortを返しながら、それが戻ってい変数がintとして宣言されていることを

static unsigned short hashcode (const char* value) { 
    int h = 0 ; 
    unsigned long length = strlen (value) ; 

    for (int i = 0 ; i < length ; i++) { 
    h = (31 * h) + value[i] ; 
    }  

    return h ; 
} 

注:元のWindowsの開発者は、この値を計算するには、次の関数を作成しました。私はドキュメントをチェックしており、OS XとWindowsは両方ともunsigned shortを2バイトと定義し、intを4と定義しています。

データ型が考慮されない場合、この関数に渡される値はこの関数は非常に大きな数値、場合によっては十桁の数値を返します。あるアルゴリズムでは、より厳密な型の別の言語でアルゴリズムを複製した場合、2081357292912430390912という値が得られました。コマンドラインユーティリティで上記の関数をwrapしたとき、同じ文字列が40576の値を返しました。これは、より長い値の切り捨てられたバージョンなので、私は推測しています。

私には2つの質問があります。まず、hashcodeunsigned shortを返すと宣言されていて、実際にそれが返ってきて、intがコンパイラに不平を言っていないのであれば、なぜですか?最初の厳密なデータ型宣言はそうではありませんか?関数とメソッドが期待どおりのデータ型を受け取って返すことを確認するには?

第2に、この切り捨ては標準的な方法ですか?まず暗黙のキャストを利用することは私には非常に奇妙なようですが、何が起こっているのかを誰かに知らせるためのコメントはありません(私は元の開発者に依頼する必要はありません)。 「特別な」ものとしてコメントされていないので、おそらくC/C++の標準的なイディオムですか?

+0

「自動鋳造」とは何ですか?それは矛盾ですか?あなたがキャストするか、そうしない。 –

+0

"暗黙的なキャスト"が良い言葉ですか? 'return h'と' return(unsigned short)h'を比較しますか? – Chuck

+7

「自動キャスト」ではなく「暗黙の変換」を意味すると思います。 C++では、キャストは明示的な変換です。 – GManNickG

答えて

2

まず、なぜ、ハッシュコードは、符号なしshortを返すように宣言され、それが戻ってint型実際にいた場合のdoesn」に関するいくつかのドキュメントですコンパイラは文句を言う?

intからunsigned shortへの変換は、暗黙のうちに

行うことができますのでどのような厳格なデータ型宣言は、最初の場所にするためのものであるということはありませんか?関数とメソッドが期待どおりのデータ型を受け取って返すことを確認するには?

はい。それはまさにここで起こっていることです。戻り値がunsigned shortであると宣言された関数は、暗黙の変換の結果としてunsigned shortを返してです。

第2に、この切り捨てが標準的な方法ですか?

はい。

キャスト付きのコードで明示的に指定されていない理由は、C++には暗黙的に実行できる変換のセットと、明示的に実行できる変換のセットがあることです。後者のセットには、ポインタと整数の間などの潜在的に危険な変換が含まれています。明示的なキャストが必要な場合を除いて暗黙的な変換を利用すると、誤って危険な変換の1つを実行することを防ぐことができます。

この実装で潜在的な問題が発生していますが、あなたの質問には関係ありません。私は細部までは行かないほうがいいと思うが、私の答えを誤解してこの機能を推奨しないでください。

+0

私はサポートされている暗黙的な変換は、 'int'から' short'のようなデータを失うことのないものに降格されると思います。 *データを失う可能性があるため、コンパイラの警告なしで作業することは明白でなければなりません。もちろん、あなたの脚注は私の好奇心を高めてくれました。だから、潜在的な問題は何ですか? – Chuck

+1

@Chuck 'strlen'の結果を格納するために間違った型を使用していますが、' strlen'を必要としないときには 'strlen'を呼びますが、大きなものは最短の文字列以外は整数オーバーフローを引き起こします。暗黙的な変換とは異なり、賢明なことをする必要はありません。 – hvd

+0

その機能はポートに存在しません。:) – Chuck

1

ここでは、自動キャストではなく暗黙的な変換を意味するものとします。私の経験から、この動作はC++を含む多くの言語に依存しています。あなたの最初の質問に答えるために、これは、割り当て元のタイプと割り当てられているタイプの間に変換シーケンスが存在する限り、コンパイラエラーを引き起こしません。

多くの場合、条件付きの人々は、== 0または!= 0を明示的に書かずに整数で渡します。

例:

int count = 10; 
while (--count); // runs 10 times 

int test = 0; 
if (test); // evaluates to false 

test = 1; 
if (test); // evaluates to true 

test = -1; 
if (test); // evaluates to true 

は、ここで暗黙的な変換すべてのhttp://en.cppreference.com/w/cpp/language/implicit_conversion

+0

整数型とポインタ型が何度もブールテストとして使われています。私はこれを別のカテゴリに置いたと思います。 – Chuck

+0

ええ、それは異なった_feel_を持っていますが、同じメカニズムです – twynn

関連する問題