2011-07-16 43 views
12
int& fun() 
{ 
    int * temp = NULL; 
    return *temp; 
} 

上記の方法では、NULLポインタの逆参照を実行しようとしています。私はこの関数を呼び出すときに例外を与えません。戻り値の型が参照渡しである場合、値渡しの場合は例外ではありません。参照のためにNULLポインタの逆参照が(次の行のように)assingされている場合でも、それは与えません。NULLポインタの逆参照による参照の割り当て

int* temp = NULL: 
int& temp1 = *temp; 

私の質問は、コンパイラが参照の際に参照解除をしないのですか?

+4

参照は内部的にはポインタとして扱われます。参照は内部で使用する構文とはまったく異なります。あなたの逆参照はポインタ値を参照に "割り当てる"だけで、NULLへの参照になります。それはメモリへのアクセスを引き起こさない。値を返すと逆参照によって0にメモリアクセスが発生し、ほとんど常にセグメンテーションが発生します。 – Nobody

+0

この記事をチェックして、NULLポインタがOOPのひどい機能であり、避けられる理由を説明します:http://www.yegor256.com/2014/05/13/why-null-is-bad.html – yegor256

答えて

16

ヌルポインタの参照解除は、未定義の動作です。

未定義の動作とは、何かが起こる可能性があることを意味します。したがって、この動作を定義することはできません。

確かに、このC++標準の見積もりをn回目に追加するつもりですが、そうする必要があるようです。未定義の動作について

C++標準のセクション1.3.24状態:

許容未定義の動作は予期しない結果と完全に状況を無視してから、中の翻訳またはプログラム実行中に動作の範囲(診断メッセージの発行の有無にかかわらず)環境の特徴を文書化した方法、(診断メッセージの発行を伴う)翻訳または実行を終了することなどが含まれる。

注:また
、ちょうどあなたの通知にそれを持って来るために:
関数内のローカル変数に返された参照またはポインタを使用しても、未定義の動作です。新しいものを使用してfreestore(ヒープ)上にポインターを割り当てて、そこに参照/ポインターを戻す必要があります。

EDIT:@James McNellisとして
、適切
は、返されたポインタ又は参照を使用しない場合、動作は明確に定義で、コメントで指摘しています。

+0

はい、上記のUBに同意します。しかし、私の質問は、NULLポインタまたは非NULLポインタのdereferencingが参照するためにassingedされている場合、コンパイラは逆参照操作を行うのですか? like - Int * t = NULL; Int&t1 = * t; –

+1

@G Mann:Referenceは、初期化された元の型への単なるエイリアスです。どのように実装されているのかは、コンパイラの実装の詳細です。標準では、実装する方法を定義していません。 –

+2

nullポインタを尊重すると、コードは無効になり、コンパイラは何もできません。なぜそれが何をしたのか尋ねることは意味がありません。 –

7

ヌルポインタを間接参照すると、必ずしも例外が発生するわけではありません。その動作が定義されていないことが保証されているだけです(本当に動作が何であるかについて全く保証がないということを意味します)。

*tempの式が評価されると、プログラムの動作を推論することは不可能です。

+0

私は他のポストで同じようなコメントを追加しています。はい、上記のUBに同意します。しかし、私の質問は、NULLポインタまたは非NULLポインタのdereferencingが参照するためにassingedされている場合、コンパイラは逆参照操作を行うのですか? like - Int * t = NULL; Int&t1 = * t; –

+0

ほとんどのコンパイラでは、多くの状況で参照がポインタとして実装されています。それを超えて、それはコンパイラ、設定などに依存します。 –

+0

私は間違っています。ポインタとして実装されている場合、コンパイラは参照解除操作を行っていない可能性があります。 –

1

*ヌルポインタではありません。それはUBです。(未定義の振る舞いでは、あなたの犬を火に照らして何かをやることができず、ファーブルな逸話につながるようなshroomを取ることを余儀なくされるとは決して決してできません)

Algol/Cファミリのヌルポインターの歴史と情報:http://en.wikipedia.org/wiki/Pointer_(computing)#Null_pointer

例と未定義の動作の意味:http://en.wikipedia.org/wiki/Undefined_behavior#Examples_in_C

0

私は私はあなたがTODOをしようとしているのか理解していないことを確認ください。 ** NULL **ポインタの参照解除は定義されていません。あなたはこの方法はいつもあなたのようにそれを宣言することができる値を返していないことを示したい場合には

ブールの楽しみを(&のvalをint型);

やSTLの道(STDに似::マップの挿入):

std::pair<int, bool> fun(); 

またはブースト方法:

boost::optional<int> fun(); 
4

あなたはので、NULLポインタデリファレンスに許可されていませんコンパイラはあなたがそれをしないと仮定してコードを生成することができます。とにかくやっていると、コンパイラがうまくいっているかもしれませんが、そうする必要はありません。それはあなたがそれをしてはならないと言っている契約のあなたの部分です。

この場合、コンパイラはとなります。は、警告レベルを適切に設定するだけで、コンパイル時に問題があることを伝えてくれます。

関連する問題