nmã³ãã³ãã§C/C++ã®ã·ã³ãã«ãã¼ãã«ãè¦ããC++ã®ååãã³ã°ãªã³ã°ã"C"ãªã³ã±ã¼ã¸ããããã¯ãªã³ã«ã«é¢ããã¡ã¢
åå(g++)ã¨åã å(gcc)ã®ãµã³ãã«ã³ã¼ãã使ã£ãC++ã®ãã³ã°ãªã³ã°ã"C"ãªã³ã±ã¼ã¸ã«é¢ããã¡ã¢ï¼
nmã³ãã³ãã§ãµã³ãã«ã³ã¼ãã®ã·ã³ãã«ãã¼ãã«ãè¦ããå¾ã«ãC++ããCã®é¢æ°ãå¼ã³åºãå ´åã®ãµã³ãã«ã³ã¼ãã示ã.
ç¹ã«ãªã³ã±ã¼ã¸å¨ãã®èª¬æã¯æ£ç¢ºæ§ãæ¬ ãã¦ããããããã¾ããã®ã§ã容赦ä¸ãã.ãã詳細ãªèª¬æã¯åèãªã³ã¯çãåç §ãã¦é ããã°ã¨æãã¾ã.
nmã³ãã³ã
nm ã¯ãUNIXãé¡ä¼¼ã®ãªãã¬ã¼ãã£ã³ã°ã·ã¹ãã ã«åå¨ããã³ãã³ãã§ããããã¤ããªãã¡ã¤ã«ï¼ã©ã¤ãã©ãªãå®è¡ãã¡ã¤ã«ããªãã¸ã§ã¯ããã¡ã¤ã«ï¼ã®ä¸èº«ã調ã¹ãããã«æ ¼ç´ããã¦ããã·ã³ãã«ãã¼ãã«ãªã©ã®æ å ±ã表示ããããããã°ã«ä½¿ããããã¨ãå¤ããèå¥åã®ååã®è¡çªåé¡ãC++ã®åå修飾ã®åé¡ã解決ããéã«è£å©ã¨ãã¦ç¨ããããã
GNUããã¸ã§ã¯ãã§ã¯ã髿©è½ã® nm ããã°ã©ã ã GNU Binutils ããã±ã¼ã¸ã®ä¸é¨ã¨ãã¦æä¾ãã¦ããããã® nm ã³ãã³ãã¯ä»ã®ãã¼ã«ã¨åæ§ã«ç¹å®ã®ã³ã³ãã¥ã¼ã¿ã»ã¢ã¼ããã¯ãã£ã¨ãã¤ããªãã©ã¼ãããåãã«ã³ã³ãã¤ã«ããã¦ããã®ã§ãã»ãã¥ãªãã£å°éå®¶ã¯çããããã¤ããªãã¡ã¤ã«ã調æ»ããããã«ãã¤ãã£ãã§ãªã nm ã³ãã³ããäºåã«åãæãã¦ãããã¨ãå¤ãã
ä»åã¯ããã¤ã使ã£ã¦ããµã³ãã«ã³ã¼ãã®ã³ã¼ãã®ã·ã³ãã«ãã¼ãã«ãè¦ãããC++ããCã®é¢æ°ãå¼ã³åºãå ´åã«èµ·ããåé¡çã«ã¤ãã¦è¦ã¦ããï¼
Cã®ã·ã³ãã«ãã¼ãã«
åã åã®gccã§çæããããã¤ããªãã¡ã¤ã«(hello.o, libhello.a, run)ã«å¯¾ãã¦nmã³ãã³ããå©ããçµæã以ä¸ã«ç¤ºãï¼
$ nm hello.o 0000000000000000 T print_hello U puts $ nm libhello.a hello.o: 0000000000000000 T print_hello U puts $ nm run 0000000000600728 d _DYNAMIC 0000000000600910 d _GLOBAL_OFFSET_TABLE_ 00000000004005f8 R _IO_stdin_used w _ITM_deregisterTMCloneTable w _ITM_registerTMCloneTable w _Jv_RegisterClasses 0000000000400708 r __FRAME_END__ 0000000000600720 d __JCR_END__ 0000000000600720 d __JCR_LIST__ 0000000000600948 D __TMC_END__ 0000000000600948 A __bss_start 0000000000600938 D __data_start 00000000004004c0 t __do_global_dtors_aux 0000000000600718 t __do_global_dtors_aux_fini_array_entry 0000000000600940 D __dso_handle 0000000000600710 t __frame_dummy_init_array_entry w __gmon_start__ 0000000000600718 t __init_array_end 0000000000600710 t __init_array_start 0000000000400550 T __libc_csu_fini 0000000000400560 T __libc_csu_init U __libc_start_main@@GLIBC_2.2.5 0000000000600948 A _edata 0000000000600950 A _end 00000000004005ec T _fini 00000000004003b8 T _init 0000000000400400 T _start 000000000040042c t call_gmon_start 0000000000600948 b completed.6092 0000000000600938 W data_start 0000000000400450 t deregister_tm_clones 00000000004004e0 t frame_dummy 000000000040050c T main 000000000040052c T print_hello <<============== ã³ã³!!颿°åããã®ã¾ã¾ã·ã³ãã«ãã¼ãã«ã«è¼ã£ã¦ãã U puts@@GLIBC_2.2.5 0000000000400480 t register_tm_clones
ããç¥ããã¦ããããã«ãCã§ã¯é¢æ°ã®éç¨ç¯å²ããã¡ã¤ã«åä½ã§ç®¡çãããï¼
颿°ã®éç¨ç¯å²ã«è©±ãçµã£ã¦è¨ãã°ã(颿°ã®æåã®å¤é¨å®£è¨ã«)static修飾åãä»ãã¦ãã颿°ã¯éç¨ç¯å²ããã®ãã¡ã¤ã«å é¨ã®ã¿ã¨ãªãããããå é¨ãªã³ã±ã¼ã¸ã¨è¨ãï¼
ããã§ãªã颿°(static修飾åãã¤ãã¦ããªãé常ã®é¢æ°)ã¯ãéç¨ç¯å²ãã°ãã¼ãã«ãªå¤é¨ãªã³ã±ã¼ã¸ã¨ãªããå ¨ã¦ã®ç®æããåç §å¯è½ã¨ãªãï¼
詳ããã¯K&Rã®ä»é²A(A10.2, A11.2)ãåç §ãããã°ã°ã£ã¦ãããã¨ãã¦ãCã§ã¯ãããã(颿°ã®)åå空éãå é¨ãªã³ã±ã¼ã¸ã¨å¤é¨ãªã³ã±ã¼ã¸ã®ãã£ãã2種é¡ãããªãï¼
ä¸è¨ã®nmã³ãã³ãã®çµæãè¦ã¦ã¿ãã¨ãprint_helloã¨ããååãã·ã³ãã«ãã¼ãã«ã«ç»é²ããã¦ãããã¨ããããï¼
print_helloã¯å¤é¨ãªã³ã±ã¼ã¸ã¨ãã¦å ¬éããã¦ããã颿°ã®ãããã¿ã¤ã宣è¨ãããã°ãä»ã®ãã¡ã¤ã«ããæ£ç¢ºã«ä¸æã«èå¥ãããã¨ãã§ããï¼
ãªã³ã±ã¼ã¸ã«éããåå²ã³ã³ãã¤ã«å ¨è¬ã«ã¤ãã¦ã以ä¸ã§è©³ç´°ã«è§£èª¬ããã¦ããé常ã«åèã«ãªã.
åè:(Cã«ããã)åå²ã³ã³ãã¤ã«ã¨ãªã³ã±ã¼ã¸
C++ã®ã·ã³ãã«ãã¼ãã«
䏿¹ãååã®g++ã«ãã£ã¦çæããããã¤ããªãã¡ã¤ã«(hello.o, libhello.a, run)ã«å¯¾ãã¦ãnmã³ãã³ããå©ããçµæãè¦ã¦ã¿ãã¨ã
$ nm hello.o 0000000000000000 T _Z11print_hellov U puts $ nm libhello.a hello.o: 0000000000000000 T _Z11print_hellov U puts $ nm run 00000000006007d8 d _DYNAMIC 00000000006009f0 d _GLOBAL_OFFSET_TABLE_ 00000000004006a8 R _IO_stdin_used w _ITM_deregisterTMCloneTable w _ITM_registerTMCloneTable w _Jv_RegisterClasses 00000000004005e8 T _Z11print_hellov <<============== ã³ã³!!颿°åã®åå¾ã«æåã追å ããã¦ãã 00000000004007b8 r __FRAME_END__ 00000000006007d0 d __JCR_END__ 00000000006007d0 d __JCR_LIST__ 0000000000600a28 D __TMC_END__ 0000000000600a28 A __bss_start 0000000000600a18 D __data_start 0000000000400580 t __do_global_dtors_aux 00000000006007c8 t __do_global_dtors_aux_fini_array_entry 0000000000600a20 D __dso_handle 00000000006007c0 t __frame_dummy_init_array_entry w __gmon_start__ 00000000006007c8 t __init_array_end 00000000006007c0 t __init_array_start 0000000000400600 T __libc_csu_fini 0000000000400610 T __libc_csu_init U __libc_start_main@@GLIBC_2.2.5 0000000000600a28 A _edata 0000000000600a30 A _end 000000000040069c T _fini 0000000000400480 T _init 00000000004004c0 T _start 00000000004004ec t call_gmon_start 0000000000600a28 b completed.6092 0000000000600a18 W data_start 0000000000400510 t deregister_tm_clones 00000000004005a0 t frame_dummy 00000000004005cc T main U puts@@GLIBC_2.2.5 0000000000400540 t register_tm_clones
颿°print_helloãã·ã³ãã«ãã¼ãã«ä¸ã§ã¯_Z11print_hellovã¨ããååã«ãªãã¼ã ããã¦ãããã¨ããããï¼
C++ã®ãã³ã°ãªã³ã°
C++ã§ã¯è¨èªæ©è½ã¨ãã¦ã颿°ã®ãªã¼ãã¼ãã¼ãããåå空éãåãã£ã¦ãããããCã®ãããªåç´ãªéç¨ç¯å²ã®æ±ºå®æ¹æ³ã§ã¯ååã®éè¤ãèµ·ãã£ã¦ãã¾ãï¼
ãã®ãããªåé¡ããåé¿ããããã«è¡ããã¦ããã®ãååãã³ã°ãªã³ã°ã§ããï¼
åè:C 㨠C++ è¿ãããã§é ãåå¨ - debian36ã®æ¥è¨
Cã®ã¢ã¸ã¥ã¼ã«ãC++ããå¼ã³åºãå ´åã«èµ·ããåé¡
ãã³ã°ãªã³ã°èªä½ã¯ã³ã³ãã¤ã©ãè¯ãã«è¨ãã£ã¦ããããã®ã¨ãã¦ãå®éã«ãã®ãã³ã°ãªã³ã°ãåé¡ã«ãªãã±ã¼ã¹ãCã®ã¢ã¸ã¥ã¼ã«(颿°)ãC++å´ããå¼ã³åºãå ´åã§ããï¼
C++ããCã®ã¢ã¸ã¥ã¼ã«ãå¼ã³åºããå ´åãCã®ãªãã¸ã§ã¯ããã¡ã¤ã«ãã©ã¤ãã©ãªãC++ã®ãªãã¸ã§ã¯ããã¡ã¤ã«ã«ãªã³ã¯ããå¿ è¦ãããï¼
å ã®(å¼ã³åºãå´ã®)ãªãã¸ã§ã¯ããã¡ã¤ã«ãC++ãªã®ã§ãæ±ãéç¨ç¯å²ã¨ãããåå空éã¨ããããªã³ã±ã¼ã¸ã¯C++ã®ãã®*1ãé©ç¨ããããã¨ããããªã³ã«ã«ã¯g++ã使ãå¿ è¦ããã*2ï¼
ãã®æ(ãªã³ã¯æ)ããªã³ã«ã§ããg++*3ã¯ä¸è¨ã®ä¾ã§è¨ãã°ãhello.oãlibhello.aã«ãä¾ãã°_Z11print_hellovã®ãããªãã³ã°ãªã³ã°ãããã·ã³ãã«ãæå¾ ããï¼
ããããhello.oã®å ã®ã³ã¼ããCã®ã½ã¼ã¹ã§ãããhello.oãgccã«ãã£ã¦çæãããå ´åã«ã¯ãhello.oã®ã·ã³ãã«ãã¼ãã«ã«ã¯çã®print_helloãç»é²ããã¦ããããã以ä¸ã®ããã«ãªã³ã¯ãè¡ãã¿ã¤ãã³ã°ã§ãã«ãã失æãããã¨ã«ãªãï¼
$ make gcc -Wall -c -o hello.o hello.c ar rv libhello.a hello.o ar: creating libhello.a a - hello.o g++ -Wall run.cc libhello.a -o run /tmp/ccrKBE8s.o: In function `main': run.cc:(.text+0x10): undefined reference to `print_hello()' collect2: error: ld returned 1 exit status make: *** [run] Error 1
ãã®ãããªåé¡ã«å½ãã£ã¦åãã¦ãªã³ã«ã®åå¨ãã¯ã£ããã¨èªèããã«è³ã.
ãªã³ã«ã®ã¨ã©ã¼ãè¦ã¦ãããã°ã©ããç¥ãã¹ã97ã®ãã¨ãã®ããªã³ã«ã¯éæ³ã®ããã°ã©ã ã§ã¯ãªãããæãåºãã.
94 ãªã³ã«ã¯éæ³ã®ããã°ã©ã ã§ã¯ãªã
ã¦ã©ã«ã¿ã¼ã»ãã©ã¤ã(Walter Bright)
'' ãªã³ã«ã¯å®ã¯ãã»ã©é£ããããã°ã©ã ã§ã¯ããã¾ããããããåç´ã§ããããããããã°ã©ã ã§ãããããã¨ã¨ããã°ããªãã¸ã§ã¯ããã¡ã¤ã«ã®ã³ã¼ãã»ã¯ã·ã§ã³ããã¼ã¿ã»ã¯ã·ã§ã³ãé£çµããå®ç¾©ããã¦ããã·ã³ãã«ã¨åç §ãæ¥ç¶ããã©ã¤ãã©ãªããæªè§£æ±ºã·ã³ãã«ãæ½åºããå®è¡ãã¡ã¤ã«ãæ¸ãåºããããã ãã§ããã¨ã¦ãåç´ã§ãéæ³ã§ãä½ã§ãããã¾ããããªããªã³ã«ãé£ããæãããã¨ããã°ãå¦çã®çµæã§ãããã¡ã¤ã«ã®ãã©ã¼ããããé©ãã»ã©è¤éã§ããã®ã¾ã¾ã§è§£èªãããã¨ã¯é£ããããã§ããããã ããã¨è¨ã£ã¦ããªã³ã«èªä½ãè¤éãªå¦çããã¦ããã¨ããããã§ã¯ãªãã®ã§ãã(...ä¸ç¥...)ãªã³ã«ãã¡ãã»ã¼ã¸ãåºããæããã®åå ãããã«ã¯ããããªããã¨ã確ãã«ããã¾ããããããããã§ãããªã³ã«ãç¹ã«è¤éãªå¦çããã¦ããããã§ã¯ãªãã¨ãããã¨ã¯å¸¸ã«å¿µé ã«ç½®ãã¹ãã§ããããå¦çèªä½ã¯ç°¡åã ããã©ãããã®çµæã§ãããã®ãè¤éã§ã詳ããæ¤è¨¼ããã®ããªããªãé¢åã¨ãããã¨ãªã®ã§ãã"
(â» æ¸ç±ãããã°ã©ããç¥ãã¹ã97ã®ãã¨ãã®å 容ãã©ã¤ã»ã³ã¹CC BY 3.0ã®å ã§ä¸é¨æç²)
話ãå ã«æ»ãã¦ããã®Cã®ãªãã¸ã§ã¯ããã¡ã¤ã«ã¨C++ã®ãªãã¸ã§ã¯ããã¡ã¤ã«ã§ãã·ã³ãã«ãã¼ãã«ã«ç»é²ããã¦ãã颿°ã®èå¥åãä¸è´ããªãåé¡ãåé¿ããã«ã¯ãC++å´ã§"C"ãªã³ã±ã¼ã¸ã«print_helloãç»é²ãããã¨ãããã¨ãããªããã°ãªããªã*4ï¼
Cã®ã¢ã¸ã¥ã¼ã«ã"C"ãªã³ã±ã¼ã¸ã«ç»é²ãã
C++ã§ã¯ãå°ãªãã¨ã"C++"ãªã³ã±ã¼ã¸ã¨"C"ãªã³ã±ã¼ã¸ãããï¼
ããã©ã«ãã§C++ãªã³ã±ã¼ã¸ã«ã·ã³ãã«ãç»é²ããããããextern "C"ã§å¼ã³åºã颿°ã"C"ãªã³ã±ã¼ã¸ã«æå®ãã¦ããã¨ããªã³ã«ãæå¾ ããã·ã³ãã«åããã³ã°ãªã³ã°åã®åå(print_hello)ã«ãªãããªã³ã¯ããéã«Cã®ã¢ã¸ã¥ã¼ã«ãå«ããªãã¸ã§ã¯ããã¡ã¤ã«ãã©ã¤ãã©ãªã¨ä¸æ´åãèµ·ãããªããªãï¼
Cããã®å¤é¨çµåã®æå®ã«å ãããªã³ã±ã¼ã¸æå®ã®ç¨æ³ãå ãã£ã¦ããã C++ã§ã¯ååï¼é¢æ°åã夿°åãªã©ï¼ã«å¯¾ãã¦å¤éå®ç¾©ãåå空éãåå®å ¨ã®ä¿éãªã©ã®é½åãããå¤ãã®ã³ã³ãã¤ã©ã¯ååä¿®é£¾ãæ½ãCã¨ã¯ç°ãªã£ãååããªã³ã«ã«å¯¾ãã¦ç¨ãã¦ããããã®ååã®ä¿®é£¾ã®ä»æ¹ãæå®ããã®ããªã³ã±ã¼ã¸æå®ã§ãããå°ãªãã¨ã"C"ã¨"C++"ã®2種é¡ã®ãªã³ã±ã¼ã¸ã使ç¨ã§ãããä½ãæå®ããªãã¨"C++"ã«ãªãã"C"ãªã³ã±ã¼ã¸ã§ã¯ååã®å¤å½¢ãææ¢ãCã¨äºæã®ååããªã³ã«ã«å¯¾ãã¦ç¨ãããã¨ãæå³ãããããã«ããCã¨C++ãæ··å¨ããã¦ããã°ã©ã ãä½ãã¨ãã«ä½¿ãããã
å®éã«ãgccã¨g++ãæ··å¨ããå ´åã®ãµã³ãã«ã³ã¼ãã示ãï¼
makeã§ã©ã¤ãã©ãª(.a)ã®ãã«ãã管çãããµã³ãã«(gccã¨g++ã®æ··å¨ver)
makeãå©ãã¨ä»¥ä¸ã®ããã«gccã¨g++ãæ··å¨ããã«ãé¢ããããã«ãã䏿ãè¨ã£ã¦ãããã¨ããããï¼
å½ç¶ãhello.oãrunã«nmã³ãã³ããå©ãã¨ã·ã³ãã«ãã¼ãã«ã«ã¯ãã³ã°ãªã³ã°åã®print_helloãç»é²ããã¦ããï¼
$ make gcc -c -o hello.o hello.c ar rv libhello.a hello.o ar: creating libhello.a a - hello.o g++ -Wall run.cc libhello.a -o run
ãã®å ´åãhello.hã¯C++ã§ããrun.ccãããCã§ããhello.cããã#includeããã¦ãããããè¨å·å®æ°__cplusplus
ã«ãã£ã¦ãC++ã®å ´åã«ã ã"C"ãªã³ã±ã¼ã¸æå®ãè¡ãããã«ããªããã°ãªããªãï¼
ãããCã®ã¢ã¸ã¥ã¼ã«ããããªã«å¤§ããªãã®ã§ãªãå ´åã«ã¯ãCã®ã³ã¼ããg++ã§ã³ã³ãã¤ã«ãã¦ãã¾ãæãããããCã®ã¢ã¸ã¥ã¼ã«ã巨大ãªã©ã¤ãã©ãªã§ãããã½ã¼ã¹ã³ã¼ããæå ã«ããã¨ãã¦ããg++ã§ã³ã³ãã¤ã«ãããã¨ããã¨å¤§éã®ä¿®æ£*5ãå¿ è¦ã«ãªãã¨ããå ´åã«ã¯ãä¸è¨ã®æ¹æ³ã§ãªã³ã¯ãããã¨ãã§ããï¼
åè:C 㨠C++ è¿ãããã§é ãåå¨ ãã®2 - debian36ã®æ¥è¨

ããã°ã©ããç¥ãã¹ã97ã®ãã¨
- ä½è : åç°å人,Kevlin Henney,å¤ç®å¤§
- åºç社/ã¡ã¼ã«ã¼: ãªã©ã¤ãªã¼ã¸ã£ãã³
- çºå£²æ¥: 2010/12/18
- ã¡ãã£ã¢: åè¡æ¬ï¼ã½ããã«ãã¼ï¼
- è³¼å ¥: 58人 ã¯ãªãã¯: 2,107å
- ãã®ååãå«ãããã° (343ä»¶) ãè¦ã
äºåäºæ¥åçä¹±ã10æ¥ç®(ã®å)ã®è¨äº
*1:C++ã®ããã©ã«ãã¯C++ãªã³ã±ã¼ã¸
*2:ãªãã¸ã§ã¯ããã¡ã¤ã«ã®ã·ã³ãã«ãã¼ãã«ã«ã¯ãã³ã°ãªã³ã°ããããã®ãç»é²ããã¦ããã®ã§
*3:ãã¡ãããªãã¸ã§ã¯ããã¡ã¤ã«çææã«ã¯g++ã¯ã³ã³ãã¤ã©ã¨ãã¦åã
*4:"ã·ã³ãã«ãã¼ãã«ã«é¢æ°ãç»é²"ãªã©ã¨ãã表ç¾ããä¸è¬çãã©ããã¯ãããã¾ãã
*5:ã¨ã©ã¼ã¨ã¾ã§ã¯è¡ããã¨ãã大éã®è¦åãç®ã®åã«çµ¶æãã