Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
C言語を知らない人がびっくりしそうなC言語の特徴 ~変数定義編~
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Satoru Takeuchi
PRO
January 17, 2023
Technology
520
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
C言語を知らない人がびっくりしそうなC言語の特徴 ~変数定義編~
以下動画のテキストです。
https://youtu.be/g7ZcZTkOAl4
Satoru Takeuchi
PRO
January 17, 2023
More Decks by Satoru Takeuchi
See All by Satoru Takeuchi
Rook: Intro and Deep Dive with Ceph
sat
PRO
1
38
Machine Check Exception
sat
PRO
2
51
バイナリダンプの模様を読む
sat
PRO
0
71
cpコマンドはディスク上でデータを コピーしないことがある
sat
PRO
3
57
114-ファイルのshallow_copy.pdf
sat
PRO
2
41
113-Btrfsのスナップショット.pdf
sat
PRO
0
23
システム強制終了時にファイルシステムの整合性を保つ~ コピーオンライト編 ~
sat
PRO
0
62
システム強制終了時に ファイルシステムの整合性を保つ ~ ジャーナリング編 ~
sat
PRO
2
68
ファイルシステムの整合性を回復するfsck
sat
PRO
1
74
Other Decks in Technology
See All in Technology
plamo-3-translateの開発
pfn
PRO
0
280
LLMリーダーボードアップデートに向けたAgentic Math_SWEのトレースについて
nejumi
0
210
toio・myCobotでフィジカルAIっぽいことを行うための検討(とりあえず調査) / フィジカルAI LT(IoTLTによる開催)
you
PRO
0
280
メルカリのグローバルアプリで挑んだ AlloyDB 運用と課題解決の実践記
hatappi
0
230
AI駆動開発は個人技からチーム戦へ:組織でAIを使いこなすための実践設計
moongift
PRO
0
450
攻撃と防御で学ぶAI時代のプロダクトセキュリティ演習
recruitengineers
PRO
1
390
QAエンジニア起点で進める、SmartHRにおける信頼性向上について
kaomi_wombat
1
110
AI時代の強いチームの作り方
yuukiyo
24
15k
Goでデータパイプラインを作ろう
sansantech
PRO
0
250
20260801_スクフェス大阪
kgnkhkr
1
1.2k
【CEDEC2026】次世代デジタルカードゲームのサーバー設計と運用 〜『Shadowverse: Worlds Beyond』の舞台裏~
cygames
PRO
0
870
PLaMoを毎日の開発で使い育てていく
pfn
PRO
0
180
Featured
See All Featured
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.1k
A Modern Web Designer's Workflow
chriscoyier
698
190k
Unsuck your backbone
ammeep
672
58k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
400
The #1 spot is gone: here's how to win anyway
tamaranovitovic
3
1.1k
Thoughts on Productivity
jonyablonski
76
5.3k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.5k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
The untapped power of vector embeddings
frankvandijk
2
1.8k
The Spectacular Lies of Maps
axbom
PRO
1
890
Docker and Python
trallard
47
4.1k
[SF Ruby Conf 2025] Rails X
palkan
2
1.2k
Transcript
C言語を知らない人がびっくりしそうな C言語の特徴 ~変数定義編~ Jan. 17th, 2023 Satoru Takeuchi twitter: satoru_takeuchi
はじめに • 想定聴衆 ◦ 「C言語は聞いたことはあるがどんなものか知らない」という人 ◦ メモリ管理を自分でしなくていいプログラミング言語を使っている人 ▪ ここ十数年で生まれた言語はだいたいそう •
はなすこと ◦ 想定聴衆に向けてC言語の特徴を紹介 ◦ 今回は変数定義について • 環境 ◦ OS: Ubuntu 20.04/x86_64 ◦ gcc: Ubuntu 9.4.0-1ubuntu1~20.04.1
変数定義時の振る舞い • ほとんどの人が思い浮かべる挙動 ◦ デフォルトの値に初期化される • C言語の挙動 ◦ 変数を定義するだけでは何が入っているかは未定義 ◦
別の関数を呼び出したときに定義した別のデータの残骸がのこっているかも
サンプルコード1 1. main()の中で変数iを定義 2. iの値を表示 • 実行結果はどうなる? ◦ 直観的には0を表示 #include
<stdio.h> int main(void) { int i; printf("%d\n", i); }
サンプルコード1の実行結果 • 0が表示された ◦ C言語としてiを0に初期化しているのではなく、「たまたまこうなった」だけ #include <stdio.h> int main(void) {
int i; printf("%d\n", i); }
サンプルコード2 1. foo()を呼ぶ 1.1. 変数iを定義して100で初期化 2. bar()を呼ぶ 2.1. 変数iを定義して初期化はしない 2.2.
iの値を表示 • 実行結果はどうなる? ◦ 現代的な言語なら0になりそう #include <stdio.h> void foo(void) { int i = 100; } void bar(void) { int i; printf("%d\n", i); } int main(void) { foo(); bar(); }
サンプルコード2の実行結果 • 初期化してないbar()内の変数iの値が100 #include <stdio.h> void foo(void) { int i
= 100; } void bar(void) { int i; printf("%d\n", i); } int main(void) { foo(); bar(); }
挙動の説明 1. 前提知識となるスタックの説明 2. サンプルコード2の挙動の説明
スタックとは • プログラムの関数呼び出しの流れとローカル変数を管理するしくみ • データ構造はスタック(であるがゆえにスタックという名前がついている • 関数を呼び出すたびにローカル変数を含むスタックフレームというものをpushする というイメージ • 一般にメモリアドレスの大きな方向から小さな方向に伸びる
スタックの説明(1/4) #include <stdio.h> void bar() { int i = 100;
} void foo() { int i = 10; bar(); } void main() { int i = 1; foo(); } メモリ スタック … … いろいろ mainのiの値(1) 0 大きい アドレス 📝 戻りアドレスとか フレームポインタとか
スタックの説明(2/4) #include <stdio.h> void bar() { int i = 100;
} void foo() { int i = 10; bar(); } void main() { int i = 1; foo(); } メモリ スタック … … いろいろ mainのiの値(1) 0 大きい アドレス fooのいろいろ fooのiの値(10) push
スタックの説明(3/4) #include <stdio.h> void bar() { int i = 100;
} void foo() { int i = 10; bar(); } void main() { int i = 1; foo(); } メモリ スタック … … いろいろ mainのiの値(1) 0 大きい アドレス fooのいろいろ fooのiの値(10) barのいろいろ barのiの値(100) push
スタックの説明(3/4) #include <stdio.h> void bar() { int i = 100;
} void foo() { int i = 10; bar(); } void main() { int i = 1; foo(); } メモリ スタック … … いろいろ mainのiの値(1) 0 大きい アドレス fooのいろいろ fooのiの値(10) ゴミ ゴミ(100) pop
スタックの説明(3/4) #include <stdio.h> void bar() { int i = 100;
} void foo() { int i = 10; bar(); } void main() { int i = 1; foo(); } メモリ スタック … … いろいろ mainのiの値(1) 0 大きい アドレス ゴミ ゴミ(10) ゴミ ゴミ(100) pop
サンプルコード2の挙動の説明 #include <stdio.h> void foo(void) { int i = 100;
} void bar(void) { int i; printf("%d\n", i); } int main(void) { foo(); bar(); } メモリ スタック … … いろいろ 0 大きい アドレス
サンプルコード2の挙動の説明 #include <stdio.h> void foo(void) { int i = 100;
} void bar(void) { int i; printf("%d\n", i); } int main(void) { foo(); bar(); } メモリ スタック … … いろいろ 0 大きい アドレス fooのいろいろ fooのiの値(100) push
サンプルコード2の挙動の説明 #include <stdio.h> void foo(void) { int i = 100;
} void bar(void) { int i; printf("%d\n", i); } int main(void) { foo(); bar(); } メモリ スタック … … いろいろ 0 大きい アドレス ゴミ ゴミ(100) pop
サンプルコード2の挙動の説明 #include <stdio.h> void foo(void) { int i = 100;
} void bar(void) { int i; printf("%d\n", i); } int main(void) { foo(); bar(); } メモリ スタック … … いろいろ 0 大きい アドレス barのいろいろ barのi(100) push 初期化していないので fooのゴミが残っている!
まとめ • C言語では変数定義時に初期化しないと、どんな値が入っているかは未定義 ◦ 現代的な言語のように必ず初期化するより高速だが危なっかしい ◦ 変なデータが見えてしまってセキュリティホールになることも • あくまで「未定義」なので、環境によって結果は異なる