質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

4回答

1047閲覧

【C++】int i = i; の挙動について

shukrin

総合スコア14

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2022/11/23 09:38

質問

タイプミスから気づいたのですが、以下のような変数宣言がコンパイルエラーにならないようです。

C++

1int i = i;

実際にiの中に入る値は直前までの挙動によるようです。

C++

1int i = i; 2std::cout << i << "\n"; // 0

C++

1int x = 1; 2int i = i; 3std::cout << i << "\n"; // 16

このような挙動になる理由はなぜなのでしょうか?
C++やC言語に詳しい方がいらっしゃったらぜひお教えいただけると幸いです。

補足情報(FW/ツールのバージョンなど)

C++17
g++.exe (x86_64-win32-seh-rev0, Built by MinGW-W64 project) 8.1.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

このような挙動になる理由はなぜなのでしょうか?

(動作が明記されたコンパイラを除いて)考えてはいけません

int iの段階で副作用完結点を迎えて、これ以降にiを使った式を書くことが可能となりますが、未初期化の変数を参照した結果は未定義です。

なにやら意味ありげな値が入っていようが、そこでクラッシュしようが、妙な最適化がかかって想定しない動作をするプログラムになろうが、コンパイルに失敗しようが、鼻から悪魔が飛び出そうが、「何が起きても仕様上は問題ない」、ということになっています。

コンパイラごとに文書化されたものがあってそれに従う、あるいは未定義の動作の奇妙さを楽しむ、というような場合を除けば、このようなコードは書くことを避けることに集中してください。

投稿2022/11/23 14:46

maisumakun

総合スコア145192

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

上のお三方の回答がほぼ答えですが、「具体的にどういう挙動の結果そうなるのか詳しく知りたい!」ってなられた場合のときのためによくわかる解説ページを紹介しておきます。
https://aonasuzutsuki.hatenablog.jp/entry/2018/12/21/111450
内容見て「よくわからん」ってなったら大人しくmaisumakunさんがおっしゃっているように脳死で絶対初期化するとだけ覚えておけば大丈夫です。

投稿2022/11/24 01:09

pig_vba

総合スコア807

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ローカル変数は、初期化しなければデタラメな値が入ってます
それだけのはなしですね

以下のような変数宣言がコンパイルエラーにならないようです。

ワーニングが出ませんか?

投稿2022/11/23 10:03

編集2022/11/23 10:06
y_waiwai

総合スコア87784

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

int i=のところまでiの宣言は完了していて変数として成立している、ということなのでしょうね。

さて。C/C++の変数とはつまりメモリ上のデータです。
メモリってのは、必要に応じて湧いてくるものではなく、もともとずら~っと並んでいるメモリデバイスがあって「ここからここまでをこの変数に使いましょう」と仕切って使うものです。で、使い終わったらそのメモリは無くなるわけではなく、ただ「もう使うのやめた」とその領域の管理が放棄されるだけ。
さて、また新たに変数が必要になればまた、では(前と同じ範囲とは限らない)ここからここまでをこの変数に使いましょうとなるわけですが、使い始めに自動では初期化などするわけではなく、前に書かれたデータがそのまま残っているのです。そのような意味で、C/C++では宣言したあとのローカル変数の値は(別途初期化しない限り)「不定」ということになっています。「不定」というのは(決してメモリの値がふらふらと変わるという意味ではなく)プログラムのその時点までの動作だけでは変数に入っている値が決まらないことがある、という意味です。そのコンピュータがその時点までどのように動作してきたか、極端には電源を入れた時のノイズなども関係するかも知れません。

投稿2022/11/23 12:03

thkana

総合スコア7652

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問