Practical Programming in C - Lec01
http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-087-practical-programming-in-c-january-iap-2010/index.htm をやってみることにした。学んだことをメモしていく。
gccオプション
-I
includeヘッダのpathを指定。
-g
Produce debugging information in the operating system's native format (stabs, COFF, XCOFF, or DWARF 2). GDB can work with this debugging information.
-O
コンパイラの最適化レベルを決める。-O0は最適化をしない。
-Wall
warningsをすべてonにする。
gdbとvalgrind
gdbはGNU Debuggerで、gccの-gオプションと組み合わせることでdebugができる。 valgrindはメモリ関連の問題を解析するためのツール。
/proc/[pid]/maps
メモリがどのように確保されているか、知ることができる。 http://www.atmarkit.co.jp/flinux/special/proctune/proctune01b.html http://linuxjm.sourceforge.jp/html/LDP_man-pages/man5/proc.5.html
配列のメモリ確保
テキストには書いてないが、どうなるか調べてみた。
#include <stdio.h> #include <unistd.h> int main(void) { int i; int x[] = { 1, 2, 3 }; for (i = 0; i < 10; i++) { printf("%p\n", &x[i]); printf("%d\n", x[i]); } }
0x7ffff4e79a40 1 0x7ffff4e79a44 2 0x7ffff4e79a48 3 0x7ffff4e79a4c 3 0x7ffff4e79a50 0 0x7ffff4e79a54 0 0x7ffff4e79a58 830598365 0x7ffff4e79a5c 59 0x7ffff4e79a60 0 0x7ffff4e79a64 0
危険。
static宣言
関数にstatic宣言をするとどうなるか?プログラミング言語Cには「外部変数あるいは関数に適用されるstatic宣言は、そのオブジェクトの通用範囲をコンパイルされつつあるソース・ファイルの残りの部分に限定される役割を持つ。」とある。日本語訳が変だが脳内変換すると、コンパイルしているソースからしか見えないということ。
static.h
static int static_function(void);
static.c
#include "static.h" static int static_function(void) { return 1; }
hello.c
#include <stdlib.h> #include <stdio.h> #include "static.h" int main(void) { printf("Hello Static Function%d\n", static_function()); exit(0); }
とすると
$ gcc static.c hello.c -o hello.o && ./hello.o static.h:19: warning: ‘static_function’ used but never defined Undefined symbols for architecture x86_64: "_static_function", referenced from: _main in cc96NBns.o ld: symbol(s) not found for architecture x86_64 collect2: ld returned 1 exit status
となる。
次に関数内部の変数にstatic宣言をしてみる。プログラミング言語Cには「内部的なstatic変数は特定の関数に局所的である。(中略)内部的なstatic変数には、単一の関数において内輪で永久的なメモリが与えられることを意味する。」とある。
static.c
int function(void) { static int i = 0; i++; return i; }
hello.c
int main(void) { int i; for ( i = 0; i < 3; i++ ) { printf("Hello Static Variable%d\n", function()); } exit(0); }
$ gcc static.c hello.c -o hello.o && ./hello.o Hello Static Variable1 Hello Static Variable2 Hello Static Variable3
static宣言のまとめ
- 関数・外部変数: 外部から参照できなくなる。Javaのprivate宣言に近い。
- 内部変数: メモリスタックに積まれず、静的に確保される。