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
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Satoru Takeuchi
PRO
January 17, 2023
Technology
1
500
C言語を知らない人がびっくりしそうなC言語の特徴 ~変数定義編~
以下動画のテキストです。
https://youtu.be/g7ZcZTkOAl4
Satoru Takeuchi
PRO
January 17, 2023
Tweet
Share
More Decks by Satoru Takeuchi
See All by Satoru Takeuchi
書籍執筆での生成AIの活用
sat
PRO
1
300
ChatGPTに従って体調管理2026
sat
PRO
0
150
eBPF
sat
PRO
1
110
waruiBPF
sat
PRO
0
110
eBPFとwaruiBPF
sat
PRO
5
3.9k
Pythonのコードの気になる行でスタックトレースを出す
sat
PRO
1
100
ソースコードを読むときの思考プロセスの例 ~markdownのレンダリング方法を知りたかった2 markdownパッケージ~
sat
PRO
0
200
様々なファイルシステム
sat
PRO
0
340
ソースを読む時の思考プロセスの例-MkDocs
sat
PRO
1
430
Other Decks in Technology
See All in Technology
Context Engineeringの取り組み
nutslove
0
380
プロダクト成長を支える開発基盤とスケールに伴う課題
yuu26
4
1.4k
私たち準委任PdEは2つのプロダクトに挑戦する ~ソフトウェア、開発支援という”二重”のプロダクトエンジニアリングの実践~ / 20260212 Naoki Takahashi
shift_evolve
PRO
2
210
usermode linux without MMU - fosdem2026 kernel devroom
thehajime
0
240
AWS Network Firewall Proxyを触ってみた
nagisa53
1
250
ブロックテーマでサイトをリニューアルした話 / 2026-01-31 Kansai WordPress Meetup
torounit
0
480
10Xにおける品質保証活動の全体像と改善 #no_more_wait_for_test
nihonbuson
PRO
2
340
SREが向き合う大規模リアーキテクチャ 〜信頼性とアジリティの両立〜
zepprix
0
480
広告の効果検証を題材にした因果推論の精度検証について
zozotech
PRO
0
210
pool.ntp.orgに ⾃宅サーバーで 参加してみたら...
tanyorg
0
1.4k
Codex 5.3 と Opus 4.6 にコーポレートサイトを作らせてみた / Codex 5.3 vs Opus 4.6
ama_ch
0
220
Exadata Fleet Update
oracle4engineer
PRO
0
1.1k
Featured
See All Featured
Between Models and Reality
mayunak
1
200
The untapped power of vector embeddings
frankvandijk
1
1.6k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
760
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
0
400
Producing Creativity
orderedlist
PRO
348
40k
Navigating Team Friction
lara
192
16k
Statistics for Hackers
jakevdp
799
230k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.4k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Principles of Awesome APIs and How to Build Them.
keavy
128
17k
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
120
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言語では変数定義時に初期化しないと、どんな値が入っているかは未定義 ◦ 現代的な言語のように必ず初期化するより高速だが危なっかしい ◦ 変なデータが見えてしまってセキュリティホールになることも • あくまで「未定義」なので、環境によって結果は異なる