èšèªCãæŠåšã ã£ãå Žåèè
ããïŒãã®èšäºã®æŠèŠã¯2015幎ã®åãã«æ²èŒãããŸããããè³æã®åºçã«ã¯è³ããŸããã§ããã æåŸã«ãç§ã®ã©ã€ãã£ã³ã°ãã¹ã¯ã®åŒãåºãã«ã¯ãäžèšã®ããã©ãããã®ã¡ãªããã¯ãªããšå€æããã®ã§ãå
ã®åœ¢ã§æ³šæãåèµ·ããŸãã ããã¹ãã§å€æŽãããŠããã®ã¯ã2015幎ãã2016幎ãŸã§ã®å¹Žã®ã¿ã§ãã
ãããŠãå¿
èŠãªä¿®æ£ã説æããŸãã¯èŠæ
ã«ã€ããŠã®ã³ã¡ã³ãããã€ã§ãåãã§èããŸãã
ã ããèšäº...Cã§ã®ããã°ã©ãã³ã°ã®æåã®ã«ãŒã«ã¯ãä»ã®ããŒã«ã§åé¡ããªããã°äœ¿çšããªãããšã§ãã
å¥ã®æ¹æ³ãèŠã€ããããšãã§ããªããšãã¯ãããã°ã©ããŒã®çŸä»£ã®æããæãåºããŠãã ããã
Cããã°ã©ãã³ã°èšèªã¯1970幎代åæããååšããŠããŸããã å°éå®¶ã¯é²åã®ããŸããŸãªæ®µéã§ãCãç ç©¶ãããªããã°ãªããã芪ããé¢ä¿è
ã¯ãã°ãã°è¡ãæ¢ãŸãã«è³ããŸããã ãããã£ãŠããã®èšèªã®ã¢ã«ãŽãªãºã ã䜿çšããæåã®çµéšã«ãããããŸããŸãªããã°ã©ããŒãã¯ãŒã«ãCã«ã€ããŠç¬èªã®èããæã£ãŠããŸããã
Cã§ã®ããã°ã©ãã³ã°ã«çŽé¢ããŠãã80幎代/ 90幎代ã«åŠãã çå®ãã®ã¬ãã«ã§ç«ã¡åŸçããªãããšãéåžžã«éèŠã§ãã
ãã®èšäºãèªãã å Žåãããããææ°ã®ãã©ãããã©ãŒã ã§äœæ¥ããŠãããçŸåšã®æšæºãé å®ããŠãããããå€ããœãããŠã§ã¢ã«é¢ããç¡éã®èŠåãåç
§ããå¿
èŠã¯ãããŸããã åã
ã®äŒæ¥ããããã20幎åã®ã·ã¹ãã ãã¢ããã°ã¬ãŒãããããšãæ°ã«ããªãã£ããããå€ä»£ã®åºæºãæ°žç¶ãããããšã¯ç¡æå³ã§ãã
ã¯ããã«
æšæºC99ïŒããã§ã¯C99-ã1999幎以éã®ããã°ã©ãã³ã°æšæºããC11-ã2011幎以éã®ããã°ã©ãã³ã°æšæºããã€ãŸã11> 99ïŒã
clang, default
- ããã©ã«ãã§ã¯ãclangã¯C11ã®æ¡åŒµããŒãžã§ã³ïŒ
GNU C11
ïŒã䜿çšãããããææ°ã®ããã°ã©ã çšã®è¿œå ãªãã·ã§ã³ã¯å¿
èŠãããŸããã C11
æšæºãå¿
èŠãªå Žåã¯ã -std=c11;
æå®ããŸã-std=c11;
C99æšæºã䜿çšããå Žåã¯ã std=c99
確èªããŠãã ããã- clangã¯ã
gcc
ãããé«éã«ãœãŒã¹ãã¡ã€ã«ãã³ã³ãã€ã«ããŸãã gcc
éžæããå Žåã -std=c99
ãŸãã¯-std=c11
ãæå®ããããšãéèŠã§ãgcc
ã¯clang
ããããœãŒã¹ãã¡ã€ã«ã®äœæã«æéãclang
ãŸãããããé«éãªã³ãŒããçæããå ŽåããããŸãã ããã©ãŒãã³ã¹ãšååž°ãã¹ãã®çµæã®æ¯èŒç¹æ§ã瀺åãããŸãã- ããã©ã«ãã§ã¯ã
gcc-5
ïŒ clang
ãããªïŒ GNU 11
ã¢ãŒãã§åäœããŸãããC11ãŸãã¯C99ãå¿
èŠãªå Žåã¯ã -std=c11
ãŸãã¯-std=c99
ãæå®ããå¿
èŠããããŸãã
æé©å
-O2ã-O3ã
éåžžã
-O2
ãé©ããŠããŸããã
-O3
å¿
èŠãªå Žå
-O3
ãããŸãã®ã§ãäž¡æ¹ã®ãªãã·ã§ã³ïŒç°ãªãã³ã³ãã€ã©ãŒãå«ãïŒããã¹ãããæãå¹ççãªå®è¡å¯èœãã¡ã€ã«ãä¿åããŸãã
-ãªã¹
-Os
ã¯ããã£ãã·ã¥ããã©ãŒãã³ã¹ã§åé¡ãçºçãããšãã«åœ¹ç«ã¡ãŸãïŒããã¯å¶ç¶ã§ã¯ãããŸããïŒã
èŠå
-Wall -Wextra -pedantic
ã³ã³ãã€ã©ã®ææ°ããŒãžã§ã³ã§ã¯
-Wpedantic
ãªãã·ã§ã³ã
-Wpedantic
ãŸãããå¿
èŠã«å¿ããŠãç¹ã«
-Wpedantic
ãåç
§ããŠãäžäœäºææ§ã®å¯èœæ§ãåºããããšãã§ããŸãã
ãã¹ã段éã§ããã¹ãŠã®ãã©ãããã©ãŒã ã«
-Werror
ããã³
-Wshadow
ã远å ããŸãã
ç°ãªããã©ãããã©ãŒã ãã³ã³ãã€ã©ãããã³ã©ã€ãã©ãªãèŠåãçºè¡ããå¯èœæ§ãããããã
-Werror
ã
-Werror
ãããšãããã°ã©ãã³ã°ããã»ã¹ãè€éã«ãªãå ŽåããããŸãã ãããŸã§ã«ééããããšã®ãªããã©ãããã©ãŒã äžã®
GCC
ããŒãžã§ã³ãæ°èŠããã³æ°èŠã®æªæã®ããéç¥ã«ããæ»æã®ããã«ã顧客ã®éçºãç¡èŠããããšã¯æããªãã
远å ã®æ¥œãããªãã·ã§ã³ã«ã¯ã
Wstrict-overflow -fno-strict-aliasing
ãŸãã
-fno-strict-aliasing
ãæå¹ã«ãããããªããžã§ã¯ããäœæããã圢åŒã§ã®ã¿ãªããžã§ã¯ããæäœã§ããŸãã Cã§ã®ããã°ã©ãã³ã°ã«ã¯ããŸããŸãªãšã€ãªã¢ã¹ã䜿çšãããããããœãŒã¹ããªãŒå
šäœãå¶åŸ¡ããå¿
èŠãçããªãéãã
-fno-strict-aliasing
ãéžæããããšãã
-fno-strict-aliasing
ããŸãã
Clang
ã䜿çšããŠããèŠåãéä¿¡ããªãããã«ããã«ã¯ãã¯ããé©åãªæ§æã
-Wno-missing-field-initializers
远å ããã ãã§ãã
GCC 4.7.0
以éã§ã¯ããã®å¥åŠãªèŠåã¯åé€ãããŸããã
éçº
ã³ã³ãã€ã«åäœ
Cã§ãããžã§ã¯ããéçºããã«ã¯ãã»ãšãã©ã®å ŽåãåçŽã«åãœãŒã¹ãã¡ã€ã«ã«ãªããžã§ã¯ããã¡ã€ã«ãå²ãåœãŠãçµæã®ãªããžã§ã¯ãã1ã€ã®å
šäœã«ã³ã³ãã€ã«ããŸãã ãã®ãããªã¹ããŒã ã¯æ®µéçãªéçºã«æé©ã§ãããããã©ãŒãã³ã¹ãšæé©åã«é¢ããŠã¯æé©ãšã¯èšããŸããã ãã®ã¢ãããŒãã§ã¯ãã³ã³ãã€ã©ã¯å€ãã®ãªããžã§ã¯ããã¡ã€ã«ãåæããŠæé©åã®å¿
èŠæ§ãèªèããŸããã
LTO-ãªã³ã¯æéã®æé©å
LTO
ã¯ãã³ã³ãã€ã«åäœã®åé¡ã®äžéšãšããŠãœãŒã¹ã®åæãšæé©åããå®è¡ãããªããžã§ã¯ããã¡ã€ã«ã®æ³šéãäžéããŒã¯ã®åœ¢ã§äœæããŸããããã«ããããªããžã§ã¯ããããŒãžããããã»ã¹ã§ãœãŒã¹ããŒã¿ãé©åã«èª¿æŽã§ããŸãã
LTO
ã¯ãå䜵ããã»ã¹ã倧å¹
ã«é
ãããå¯èœæ§ããããŸãã
make -j
圹ç«ã¡ãŸãããéçºãç¬ç«ããç¡é¢ä¿ãªæçµãšã°ãŒãã¥ãŒã¿ãŒïŒ.aã.soã.dylibããã¹ãå®è¡å¯èœãã¡ã€ã«ãå®è¡å¯èœã¢ããªã±ãŒã·ã§ã³ãªã©ïŒã§æ§æãããŠããå Žåã®ã¿ã§ãã
clang LTOGCC LTO2016幎ãŸã§ã«ã
clang gcc
ã¯è£å©
LTO
ã®äœæãåŠçããŸãããããã¯ããªããžã§ã¯ããã³ã³ãã€ã«ããæçµçã«ã©ã€ãã©ãª/ããã°ã©ã èŠçŽ ãããŒãžãããšãã«ã³ãã³ãã®ãªã¹ãã«
-flto
ã远å ããããšã§å©çšã§ããŸãã ãã ãã
LTO
ãŸã ç®ãšç®ãå¿
èŠã§ãã å Žåã«ãã£ãŠã¯ãããã°ã©ã ãçŽæ¥å®è¡ãããªãã远å ã®ã©ã€ãã©ãªãŒãä»ããŠã³ãŒãã䜿çšããå Žåã
LTO
ã¯å¯Ÿå¿ãã颿°ãŸãã¯ã³ãŒããé€å€ã§ããŸããããã¯ãäžè¬çãªåæã®éçšã§ããŠãŒãã£ãªãã£ã䜿çšãããŠããªãããšãæ€åºããããã§ããã€ãŸãã補åã®æçµããŒãžã§ã³ã§ã¯äžèŠã§ãã
Arch
-march=native
ã³ã³ãã€ã©ãŒã«ããã»ããµãŒã®ãã¹ãŠã®æ©èœã䜿çšãããèŠããŠãããŠãã ããïŒããã©ãŒãã³ã¹ãã¹ããšååž°ãã¹ãã¯éèŠã§ãïŒç°ãªãã³ã³ãã€ã©ãŒããã³/ãŸãã¯ãããã®ããŒãžã§ã³ã®çµæã®æ¯èŒåæãåŸã«ç¶ããŸãïŒããããã®å©ããåããŠãæé©åèŠçŽ ã«æªåœ±é¿ããªãããšã確èªã§ããããã§ãã
-msse2 -msse4.2
ã¯ãä»ã®éçºè
ãçšæãããªãã·ã§ã³ã䜿çšããå Žåã«å¿
èŠã«ãªãå ŽåããããŸãã
ã³ãŒãçæ
çš®é¡
æ°ããã³ãŒãã§
char, int, short, long unsigned
ãããªãã®ãèŠã€ããå Žåãããã«ãšã©ãŒããããŸãã
ææ°ã®ããã°ã©ã ã§ã¯ã
#include <stdint.h>
ãæå®ããŠãããæšæºã®ããŒã¿åãéžæããå¿
èŠããããŸãã
詳现ãªèª¬æã¯ã
stdint.h仿§ã«ãããŸããæãäžè¬çãªæšæºããŒã¿åã«ã¯æ¬¡ã®ãã®ããããŸãã
int8_t, int16_t, int32_t, int64_t
笊å·ä»ãæŽæ°ãuint8_t, uint16_t, uint32_t, uint64_t
笊å·ãªãæŽæ°;float
-32ãããæµ®åå°æ°ç¹æšæºãdouble
-64ãããæµ®åå°æ°ç¹æšæºã
泚æããŠãã ããïŒãã以äž
char
ã éåžžãCããã°ã©ãã³ã°èšèªã§ã¯ã
char
ã³ãã³ãã¯åŒã³åºãããã ãã§ãªãã誀ã£ãŠäœ¿çšãããŸãã
ãœãããŠã§ã¢éçºè
ã¯ã笊å·ãªãã®ãã€ãæäœãå®è¡ãããå Žåã§ãã
char
ã³ãã³ãã䜿çšããŠããã€ãããæå³ãç¶ããŸãã åã
ã®ç¬Šå·ãªããã€ã/ãªã¯ãããå€ã«
uint8_t
ãæå®ãã笊å·ãªããã€ã/
ãªã¯ãããå€ã®ã·ãŒã±ã³ã¹ã«
uint8_t
*ãéžæããæ¹ãã¯ããã«æ£ç¢ºã§ãã
intãåç
§ãã䟡å€ããããŸãã
èªè
ã®äžã«ã¯ãåã«
int
åŽæããŠããããšãèªããŠãã人ãããŸãã ããŒã¿åã®ãµã€ãºãå¿
èŠã«å¿ããŠå€æŽãããå Žåãæ£ããããã°ã©ã ããããšã¯æè¡çã«äžå¯èœã§ããããšã¯æ³šç®ã«å€ããŸãã
ãŸãã
inttypes.hã®èª¬æäžã«è¡šæããã
Justificationããã§ãã¯ããŠãã ãããåºå®ãããŠããªãå¹
ã®åã䜿çšããããšãå®å
šã§ãªãçç±ãæç¢ºã«èª¬æããŠããŸãã äžéšã®ãã©ãããã©ãŒã ã§ã®éçºããã»ã¹äžã«
int
16ãããã§ãããä»ã®ãã©ãããã©ãŒã ã§
int
32ãããã§ããããšã«ãã§ã«æ°ä»ããŠããå Žåã
int
䜿çšããšã«16ããããš32ãããã®åé¡é åããã¹ãããŸãããåãæ¹æ³ã§ç¶è¡ã§ããŸãã
次ã®ããºã«ãå®è¡ãããšãã«ããã«ãã¬ãã«æ§é ã®ãã©ãããã©ãŒã ã®æè¡çæ¡ä»¶ã®è€åäœå
šäœãé ã®äžã§ä¿æããç¥æµããŸã ç¿åŸããŠããªãæ®ãã®äººã®ããã«ãåºå®å¹
ã¿ã€ãã§åæ¢ããããšããå§ãããŸãã远å ã®åªåãå¿
èŠã§ãã ãŸãã¯ã説æãç°¡æœã«è¿°ã¹ãŠããããã«ããæšæºæŽæ°ããŒã¿ãä¿é²ããããã®ISO CèŠåã¯ãå®å
šã«äºæããªã倿Žã«ã€ãªããå¯èœæ§ããããŸããã
幞éã¯äžå¯æ¬ ã§ãã
ã char
䜿çšããªããã«ãŒã«ã®äŸå€
2016幎ã«
char
ã³ãã³ãã«ã¢ã¯ã»ã¹ã§ããã®ã¯ãéžæããAPIã
char
ïŒããšãã°ã
strncat, printf'ing "%s", ...
ïŒãèŠæ±ããå ŽåããŸãã¯èªã¿åãå°çšã®æååãæå®ããå ŽåïŒããšãã°ã
const char *hello = "hello";
ïŒãCããã°ã©ãã³ã°èšèªã§ã¯ãæååãªãã©ã«ïŒ "hello"ïŒã¯
char
[]ã®ããã«èŠããããã
ããã«ãC11ã¯ãã€ãã£ãUnicodeã®ãµããŒããæäŸããUTF-8æååãªãã©ã«ã¯ã
const char *abcgrr = u8"abc";
ãããªãã«ããã€ãã·ãŒã±ã³ã¹ãæäœããå¿
èŠãããå Žåã§ããåŒãç¶ã
char
䜿çšã
const char *abcgrr = u8"abc";
ã
ã {int,long,etc}
䜿çšããªãããšããã«ãŒã«ã®äŸå€
çµæã®åãŸãã¯ãã€ãã£ããã©ã¡ãŒã¿ãŒã䜿çšããŠé¢æ°ã«ã¢ã¯ã»ã¹ããå Žåã¯ã颿°ã¯ã©ã¹ãŸãã¯APIã®ç¹æ§ã«å¿ããŠåã䜿çšããŸãã
眲å
ã³ãŒãã§
unsigned
ã䜿çšããããšã
unsigned
ã§ãã ããã ããã§ãã³ã³ãã³ããèªã¿ã«ããããã ãã§ãªãã宿åã䜿çšããå¹çæ§ã«çåãæãããã倿°ã®ããŒã¿åã䜿çšããŠãåä»ãªCã®èŠåãªãã«ãŸãšããªã³ãŒããèšè¿°ããæ¹æ³ãããããŸããã åçŽãª
uint64_t
å¶éã§ããå Žåã誰ã
unsigned long long int
ãå
¥åããŸããïŒ ã¿ã€ã<stdint.h>ã®ãã¡ã€ã«ã¯ãããå
·äœçãã€æ£ç¢ºãªæå³ãæã¡ãäœè
ã®æå³ãããããäŒããã³ã³ãã¯ãã§ããããã¯ãæäœãšèªã¿ãããã®äž¡æ¹ã«ãšã£ãŠéèŠã§ãã
æŽæ°ãã€ã³ã¿ãŒ
ããããããªãã®äžäººã¯ãããããããã€ã³ã¿ãŒãªãã§
long
ãã©ãããã°ãã¹ãŠã®æ°åŠãã«ããŒãããã§ãããïŒããšå察ããã§ãããã
ãã¡ãããããªãã¯ãã®ãããªããšãèšãããšãã§ããŸãããã ãã声æãçå®ã§ãããšèšããŸããïŒ
ãã®å Žåã®ãã€ã³ã¿ãŒã®æ£ããã¿ã€ãã¯
uintptr_t
ã§ããã¡ã€ã«
<stdint.h>
ã«ãã£ãŠèšå®ãããŸãã åæã«ãéåžžã«æçšãª
ptrdiff_t
ã¯
stddef.h
ã«ãã£ãŠå®çŸ©ãããŠããããšã«æ³šæããããšãéèŠã§ãã
代ããã«ïŒ
long diff = (long)ptrOld - (long)ptrNew;
䜿çšïŒ
ptrdiff_t diff = (uintptr_t)ptrOld - (uintptr_t)ptrNew;
ãããŠãŸãïŒ
printf("%p is unaligned by %" PRIuPTR " bytes.\n", (void *)p, ((uintptr_t)somePtr & (sizeof(void *) - 1)));
ã·ã¹ãã äŸåã®ããŒã¿å
ã32ããããã©ãããã©ãŒã ã§ã¯32ããã
long
ãå¿
èŠã§ããã64çªç®ã®ãã©ãããã©ãŒã ã§ã¯64ããããå¿
èŠã§ãïŒã
ãã©ãããã©ãŒã ã«å¿ããŠã³ãŒãã§2ã€ã®ç°ãªããµã€ãºã䜿çšããçç±ã説æããã®ãé£ãããšæç¢ºã«å€æããæšè«ãçç¥ããå Žåãæçµçã«ã¯ãã·ã¹ãã äŸåã®ããŒã¿åã«åãããã
long
ã«çŠç¹ãåœãŠãããªããšæããŸãã
ãã®ãããªç¶æ³ã§ã¯ããã©ãããã©ãŒã ã®ãã€ã³ã¿ãŒå€ãæ ŒçŽããæŽæ°ããŒã¿åã§ãã
intptr_t
ãåç
§ããã®ãåççã§ãã
ææ°ã®32ããããã©ãããã©ãŒã ã§
intptr_t
ã
intptr_t
int32_t
倿ãããŸãã
ææ°ã®64ããããã©ãããã©ãŒã ã§ã¯ã
intptr_t
ã¯
int64_t
ã®åœ¢åŒãåããŸãã
ãŸãã
intptr_t
ã¯
uintptr_t
ããªã¢ã³ãã«ãããŸãã
ãã€ã³ã¿ãŒãªãã»ããã«é¢ããæ
å ±ãä¿åããã«ã¯ã
ptrdiff_t
䜿çšã
ptrdiff_t
-æžç®ããããã€ã³ã¿ãŒã®ãã©ã¡ãŒã¿ãŒãèšæ¶ã§ããã®ã¯ãã®ããŒã¿åã§ãã
æå€§å€
ã·ã¹ãã äžã®æŽæ°å€ãåŠçã§ããæŽæ°ããŒã¿åãæ¢ããŠããŸããïŒ
ååãšããŠãããã°ã©ããŒã¯æãããç¥ãããŠããä»£æ¿ææ®µãç¹ã«æ°åããªã
uint64_t
ãããããçš®é¡ã®å€ãæ ŒçŽããããã«ä»»æã®å€æ°ã䜿çšã§ãããããã§ãããå¹ççãªæè¡ç解決çããããŸãã æŽæ°ããŒã¿ã®å®å
šãªä¿åã¯ã
intmax_t
ïŒãŸãã¯
uintmax_t
ïŒã«ãã£ãŠä¿èšŒãããŸãã ããŒã¿ã®ç²ŸåºŠã圱é¿ãåããªãããšã確èªããŠãä»»æã®ç¬Šå·å€
intmax_t
å§ä»»ã§ããŸãã åæ§ã«ã
uintmax_t
ã«ãã£ãŠå§ä»»ããã笊å·ãªãæŽæ°ã
uintmax_t
ãŸãã
å¥ã®ããŒã¿å
åºç¯å²ã«ãããã·ã¹ãã äŸåã®ããŒã¿åã«ã€ããŠè©±ããŠããå Žåã
stddef.h
ã«ãã£ãŠä¿èšŒãããŠãã
size_t
ããæ°ã«å
¥ãã®ãªã¹ãã®1äœã«ãªããŸãã
å®éã
size_t
ã¯ã巚倧ãªé
åã€ã³ããã¯ã¹ãæ ŒçŽã§ããæŽæ°ãã®ãããªãã®ã§ããã€ãŸããäœæäžã®ããã°ã©ã ã®å°è±¡çãªå€äœã€ã³ãžã±ãŒã¿ãŒãä¿®æ£ã§ããŸãã
å®éã«ã¯ã
size_t
ã¯ãsizeofæŒç®åã®çµæã¿ã€ããšããŠæ©èœããŸãã
ãããã®å Žåã§ããææ°ã®ãã©ãããã©ãŒã ã§ã¯ã
size_t
ã¯
uintptr_t
ãšå®è³ªçã«åãç¹æ§ãæã€ããã32ãããããŒãžã§ã³ã§
size_t
ã
size_t
uint32_t
ã64ããã
uint64_t
ã¯
uint64_t
ãŸãã
ssize_t
ããã
ssize_t
ãããã¯ãã©ã€ãã©ãªé¢æ°ã®çµæã®åãšããŠäœ¿çšããã笊å·ä»ãã®
size_t
ã§ãããšã©ãŒã®å Žåã1ãååŸããŸãïŒæ³šïŒ
ssize_t
ã¯POSIXããã±ãŒãžã«å±ããWindowsã«ã¯é©ããŠããŸããïŒã
ç¬èªã®é¢æ°ã®ãã©ã¡ãŒã¿ãŒãèšå®ããããšã§ãã·ã¹ãã ã«äŸåããä»»æã®ãµã€ãºã«
size_t
ã䜿çšãã䟡å€ã¯ãããŸããïŒ æè¡çã«ã¯ã
size_t
ã¯
sizeof
ã®çµæã¿ã€ãã§ãããããæ°éã®ãµã€ãºãç¹å®ã®ãã€ãæ°ãšããŠæ±ºå®ãã颿°ã¯ã
size_t
ã®åœ¢åŒãåãããšãã§ããŸãã
ãã®ä»ã®ã¢ããªã±ãŒã·ã§ã³ïŒ
size_t
ã¯malloc颿°ã®åŒæ°åã§ããã
ssize_t
ã¯
read()
ããã³
write()
ã®çµæåã§ã
read()
Windowsã€ã³ã¿ãŒãã§ã€ã¹ãé€ãã
ssize_t
æäŸããããintã®ã¿ãçµæå€ã«äœ¿çšãããŸãïŒã
å°å·ã¿ã€ã
å°å·äžã«ããŒã¿åãåç
§ããªãã§ãã ããã
inttypes.hã®ã¢ããã€ã¹ã«åŸã£ãŠãåžžã«é©åãªã¿ã€ããã€ã³ã¿ãŒã䜿çšããŠãã ããã
ãã®ãªã¹ãã«ã¯ä»¥äžãå«ãŸããŸãïŒãã¡ãããããã¯çãæç²ã«ãããŸããïŒïŒ
- size_t-ïŒ
zu
- ssize_t-ïŒ
zd
- ptrdiff_t-ïŒ
td
- ãã€ã³ã¿ãŒã®åæå€ã¯ïŒ
pã§ãïŒææ°ã®ã³ã³ãã€ã©ãŒã§ã¯ã16é²ã·ã¹ãã ã§è¡šç€ºãããŸããæåã¯ãã€ã³ã¿ãŒãvoid *ã«éä¿¡ããŸãïŒ
- int64_t-"ïŒ
" PRId64
- uint64_t-"ïŒ
" PRIu64
PRI [udixXo] 64ã¹ã¿ã€ã«ãã¯ãã®ã¿ã䜿çšããŠã64ãããããŒã¿åãå°å·ããŸãã
ãªãã§ïŒ
äžéšã®ãã©ãããã©ãŒã ã§ã¯ã64ãããå€ã¯
long
颿°ã§è¡šãããä»ã®ãã©ãããã©ãŒã ã§ã¯
long
衚ãããŸããããã®ãã¯ãã¯ãããŸããŸãªãã©ãããã©ãŒã ã«æé©ãªåºæ¬ãã©ãŒãããç¹æ§ãæäŸããŸãã
ãããã®ãã©ãŒããããã¯ãããªããšããã¹ãŠã®ãã©ãããã©ãŒã ã«é©ãããã©ãŒãããæååãåæã«äœæããããšã¯äºå®äžäžå¯èœã§ããããŒã¿ã¿ã€ãã¯ã¢ã¯ã·ã§ã³ã«é¢ä¿ãªãå€åããããã§ãïŒãããŠãå°å·åã«äžèšã®å€ãèšå®ããããšã¯å®å
šã§ããã ãã§ãªããè«ççã§ãªãããšãå¿ããªãã§ãã ããïŒã
intptr_t
-ãïŒ
ãPRIdPTR
uintptr_t
-ãïŒ
ãPRIuPTR
intmax_t
-ãïŒ
ãPRIdMAX
uintmax_t
-ãïŒ
ãPRIuMAX
PRI *åœ¢åŒæå®åãžã®è¿œå ïŒãããã¯ãã¯ãã§ãããç¹å®ã®ãã©ãããã©ãŒã ã«å¿ããŠãé©åãªprintfã¯ã©ã¹æå®åã«å±éãããŸãã ãããã£ãŠã次ãæå®ããããšã¯ã§ããŸããã
printf("Local number: %PRIdPTR\n\n", someIntPtr);
代ããã«ããã¯ããæ±ã£ãŠããããšãç¥ã£ãŠã次ã®ããã«èšè¿°ããŸãã
printf("Local number: %" PRIdPTR "\n\n", someIntPtr);
泚ïŒé£æ¥ãããã¹ãŠã®è¡ã¯1ã€ã®æçµçãªçµåæååãªãã©ã«ã§ããªããã»ããµã«ãã£ãŠçµåããããããïŒ
ã¯æžåŒæååãªãã©ã«ã®æ¬äœã«å«ãŸããŸãããã¿ã€ããã€ã³ã¿ãŒã¯ãã®å€åŽã«çãŸããŸãã
C99ã§ã¯ãã©ãã§ã倿°ã®èª¬æã䜿çšã§ããŸãã
ããã¯è¡ããŸããïŒ
void test(uint8_t input) { uint32_t b; if (input > 3) { return; } b = input; }
代ããã«ã次ã®ããã«èšè¿°ããŸãã
void test(uint8_t input) { if (input > 3) { return; } uint32_t b = input; }
èŠåïŒããã°ã©ã ã®ãµã€ã¯ã«ãå¶éãããŠããå Žåã¯ãã€ãã·ã£ã©ã€ã¶ãŒã®äœçœ®ã確èªããŠãã ããã äœç³»åãããŠããªãèšè¿°ã¯ãäºæããªãé床äœäžã«ã€ãªããå ŽåããããŸãã å éåãããŠããªãéåžžã®ã³ãŒãïŒå®éã«ã¯ã»ãšãã©ã®å Žåã«äœ¿çšãããŸãïŒã®å Žåãæç¢ºæ§ã«çŠç¹ãåãããããšãæåã§ãã ãããã£ãŠãã€ãã·ã£ã©ã€ã¶ã®äœæ¥ãå®äºããçŽåŸã«ããŒã¿åãå®çŸ©ããããšã«ãããèªã¿ããããèããåäžããŸãã
C99ã§ã¯ãforã«ãŒãã䜿çšããŠã€ã³ã©ã€ã³ã«ãŠã³ã¿ãŒã®èª¬æãäœæã§ããŸãã
決ããŠæžããªãïŒ
uint32_t i; for (i = 0; i < 10; i++)
æ£ããã§ãããïŒ
for (uint32_t i = 0; i < 10; i++)
1ã€ã®äŸå€ïŒã«ãŒãã®çµäºåŸã«ã«ãŠã³ã¿ãŒã®å€ãä¿æããå Žåã¯ããã¡ãããã«ãŒãã®æ¬æã«å¯Ÿå¿ãã説æãæ¿å
¥ããªãã§ãã ããã
ææ°ã®ã³ã³ãã€ã©ã¯#pragma onceããµããŒãããŠããŸãã
ééã£ããªãã·ã§ã³ïŒ
#ifndef PROJECT_HEADERNAME #define PROJECT_HEADERNAME . . . #endif /* PROJECT_HEADERNAME */
代ããã«ã䜿çšããŸã
#pragma once
#pragma once
ãããããŒã1åã ãèŠæ±ããå¿
èŠãããããšãã³ã³ãã€ã©ãŒã«éç¥ãããããããããŒãä¿è·ããããã«äœåãªè¡ãèšè¿°ããå¿
èŠã¯ãããŸããã ãã®é¢æ°ã¯ããã¹ãŠã®ã³ã³ãã€ã©ãŒããã³ç°ãªããã©ãããã©ãŒã ã§ãµããŒããããŠãããããããŒã³ãŒããæåã§å
¥åãããããã¯ããã«å¹ççãªã¡ã«ããºã ã§ãã
ãã©ã°ãã1åãµããŒãããã³ã³ãã€ã©ãŒã®ãªã¹ãã«ããªãã·ã§ã³ã®è©³çްãªèª¬æããããŸãã
Cããã°ã©ãã³ã°èšèªã§ã¯ãèªåçã«äœæãããé
åãéçã«åæåã§ããŸãã
ã ããç§ãã¡ã¯æžããŸããïŒ
uint32_t numbers[64]; memset(numbers, 0, sizeof(numbers));
æ£ããã§ãããïŒ
uint32_t numbers[64] = {0};
Cã§äœæ¥ããå Žåãèªåçæãããæ§é ãéçã«åæåã§ããŸãã
åŸæ¥ã®ãšã©ãŒïŒ
struct thing { uint64_t index; uint32_t counter; }; struct thing localThing; void initThing(void) { memset(&localThing, 0, sizeof(localThing)); }
æ£ããïŒ
struct thing { uint64_t index; uint32_t counter; }; struct thing localThing = {0};
éèŠïŒæ§é äœãå
éšã¢ã©ã€ã¡ã³ããæäŸããå Žåã{0}ã¡ãœããã¯ãã®ç®çã®ããã«è¿œå ã®ãã€ãããŒãã«ããŸããã ãã®ãããããšãã°ãæ§é ã1ã¯ãŒãåäœã§åãããããããæ§é ç©ã®ã«ãŠã³ã¿ãŒã®åŸïŒ64ããããã©ãããã©ãŒã äžïŒã«4ãã€ãã®ã€ã³ãã³ããããå Žåã«çºçããŸãã æªäœ¿çšã®ã€ã³ãã³ããã€ããå«ãæ§é å
šäœãç¡å¹ã«ããå¿
èŠãããå Žåã¯ã8 + 4 = 12ãã€ããã䜿çšã§ããªãã«ãããããããsizeofïŒlocalThingïŒ== 16ãã€ãã§ãããã
memset(&localThing, 0, sizeof(localThing))
æå®ããŸãã
以åã«å²ãåœãŠãããæ§é ãååæåããå¿
èŠãããå Žåã¯ã以éã®å€ã®æ±ºå®ã«å
±éã®ãŒãæ§é ã䜿çšããŸãã
struct thing { uint64_t index; uint32_t counter; }; static const struct thing localThingNull = {0}; . . . struct thing localThing = {.counter = 3}; . . . localThing = localThingNull;
C99ïŒãŸãã¯ãã以éïŒã§äœæ¥ãã幞éãããã°ãåºæ¬çãªããŒãæ§é ããããã代ããã«è€åãªãã©ã«ãéžæã§ããŸãïŒ
The New CïŒCompound Literalsã2001ãåç
§ïŒã
è€åãªãã©ã«ã䜿çšãããšãã³ã³ãã€ã©ã¯äžæçãªå¿åæ§é ãèªåçã«äœæãã察å¿ããå€ãã£ãŒã«ãã«ã³ããŒã§ããŸãã
localThing = (struct thing){0};
å¯å€é·ã®é
åã¯C99ã§ç»å ŽããŸããïŒC11ã§ã¯ãå¿
èŠã«å¿ããŠéžæã§ããŸãïŒã
ãããã£ãŠã次ã®ããã«èšè¿°ããªãã§ãã ããïŒãããã¥ã¢é
åãæ±ãå ŽåããŸãã¯åã«é«éãã¹ããè¡ãå ŽåïŒã
uintmax_t arrayLength = strtoumax(argv[1], NULL, 10); void *array[]; array = malloc(sizeof(*array) * arrayLength); / * () * /
代ããã«ã以äžã瀺ããŸãã
uintmax_t arrayLength = strtoumax(argv[1], NULL, 10); void *array[arrayLength];
éèŠïŒéåžžã®é
åãšåæ§ã«ãå¯å€é·ã®é
åãïŒèŠåãšããŠïŒã¹ã¿ãã¯äžã«äœæãããŸãã 300äžèŠçŽ ã®éåžžã®é
åãéçã«äœæã§ããªãå Žåããã®æ§æã䜿çšããŠåããµã€ãºã®åçé
åãçæããããšããªãã§ãã ããã ãããã¯ã¹ã±ãŒã©ãã«ãªPython / Rubyèªåãªã¹ãã§ã¯ãããŸããã ããã°ã©ã ã®èµ·åäžã«é
åã®é·ããèšå®ããã¹ã¿ãã¯ã«å¯ŸããŠå€§ãããããšå€æããå Žåãæ··ä¹±ãå§ãŸããŸãïŒæ©èœäžå
šãã»ãã¥ãªãã£äžã®åé¡ïŒã å¯å€é·é
åã¯ãç¹å®ã®ã¿ã¹ã¯ãå®è¡ããããã«èšèšãããåã
ã®ç¶æ³ã«çæ³çã§ããããã¹ãŠã®ã¿ã€ãã®ãœãããŠã§ã¢ãéçºããããã«äœ¿çšããªãã§ãã ããã äžåºŠ3ã€ã®èŠçŽ ã®é
åãçæããå¿
èŠãããããã1ã€ã¯300äžã«éãããšãå¯å€é·ã®é
åã䜿çšããããšã«ã»ãšãã©äŸ¡å€ããããŸããã
ã¯ããVLAæ§æãçè§£ããŠãããšäŸ¿å©ã§ãïŒãŸãã¯ã補åã®1åéãã®è¿
éãªãã¹ããè¡ãå¿
èŠãããå ŽåïŒã åæã«ãããã°ã©ã å
šäœãã¯ã©ãã·ã¥ãããšãããããåãçµã¿ã¯æ²åã«ãªããŸããèŠçŽ ãµã€ãºããã§ãã¯ããããã®æ£ç¢ºãªãã©ã¡ãŒã¿ãŒãå¿ãããã远å ã®ã¹ã¿ãã¯ã¹ããŒã¹ããªãäžæ
£ããªã¿ãŒã²ãããã©ãããã©ãŒã ã«çŽé¢ããŠãããšããäºå®ãèŠå€±ãã ãã§ãã
: ,
arrayLength
â ( ; 4 ). ( ), , , , 99 VLA,
malloc
.
: , , , VLA. - VLA , , , , , .
C99 .
, .
:
void processAddBytesOverflow(uint8_t *bytes, uint32_t len) { for (uint32_t i = 0; i < len; i++) { bytes[0] += bytes[i]; } }
:
void processAddBytesOverflow(void *input, uint32_t len) { uint8_t *bytes = input; for (uint32_t i = 0; i < len; i++) { bytes[0] += bytes[i]; } }
, . « »,
uint8_t
. , , ,
char *
, - . ,
void *
, , , , , .
, , , . , , . - Unaligned Memory Access (: , , , ).
C99
<stdbool.h>
, true 1, false â 0.
/ true or false,
int32_t
, 1 0 (, , 1 -1; : 0 â success, 1 â failure? 0 â success, -1 â failure?).
, , , API , , . , , , « , ».
:
void *growthOptional(void *grow, size_t currentLen, size_t newLen) { if (newLen > currentLen) { void *newGrow = realloc(grow, newLen); if (newGrow) { grow = newGrow; } else { free(grow); grow = NULL; } } return grow; }
:
bool growthOptional(void **_grow, size_t currentLen, size_t newLen) { void *grow = *_grow; if (newLen > currentLen) { void *newGrow = realloc(grow, newLen); if (newGrow) { *_grow = newGrow; return true; } free(grow); *_grow = NULL; return true; } return false; }
, , :
typedef enum growthResult { GROWTH_RESULT_SUCCESS = 1, GROWTH_RESULT_FAILURE_GROW_NOT_NECESSARY, GROWTH_RESULT_FAILURE_ALLOCATION_FAILED } growthResult; growthResult growthOptional(void **_grow, size_t currentLen, size_t newLen) { void *grow = *_grow; if (newLen > currentLen) { void *newGrow = realloc(grow, newLen); if (newGrow) { *_grow = newGrow; return GROWTH_RESULT_SUCCESS; } return GROWTH_RESULT_FAILURE_ALLOCATION_FAILED; } return GROWTH_RESULT_FAILURE_GROW_NOT_NECESSARY; }
æžåŒèšå®
, .
50 , - . , .
â .
, 2016 , , â clang-format. clang-format C-. , .
clang-format:
#!/usr/bin/env bash
clang-format -style="{BasedOnStyle: llvm, IndentWidth: 4, AllowShortFunctionsOnASingleLine: None, KeepEmptyLinesAtTheStartOfBlocks: false}" "$@"
(
cleanup-format
):
matt@foo:~/repos/badcode% cleanup-format -i *.{c,h,cc,cpp,hpp,cxx}
-i , .
, :
#!/usr/bin/env bash # : clang-tidy , # . find . \( -name \*.c -or -name \*.cpp -or -name \*.cc \) |xargs -n1 -P4 cleanup-tidy # clang-format , 12 # () . find . \( -name \*.c -or -name \*.cpp -or -name \*.cc -or -name \*.h \) |xargs -n12 -P4 cleanup-format -i
, cleanup-tidy. , , :
#!/usr/bin/env bash clang-tidy \ -fix \ -fix-errors \ -header-filter=.* \ --checks=readability-braces-around-statements,misc-macro-parentheses \ $1 \ -- -I.
clang-tidy
â . :
readability-braces-around-statements
â if/while/for ;
, « » . . , , « !», â , - . , , , , , .
misc-macro-parentheses
â , .
clang-tidy
â , , , , . ,
clang-tidy
â ,
clang-format
, .
, , âŠ
ã³ã¡ã³ã
.
1000 (1500 ). ( ..), .
malloc
calloc
. .
calloc(object count, size per object)
,
#define mycalloc(N) calloc(1, N)
.
:
- alloc , ;
- calloc , ( , , 30- , ..);
- calloc(element count, size of each element) ;
- malloc() , , ;
- calloc valgrind, / , calloc 0;
- â . , , , ;
- calloc () , , malloc(), calloc(), â , , . , calloc() . , calloc(element count, size of each element).
, , , .
,
calloc()
, :
Benchmarking fun with calloc() and zero pages (2007)Copy-on-write in virtual memory management2016 -
calloc()
( , 64 , , , ). « » , « », .
:
calloc()
â , .
calloc()
realloc()
, . .
realloc()
,
memset()
.
memset
( )
memset
(ptr, 0, len, () ( , ).
memset()
â , , ( {0} , ).
ãããã«
, , . , , , , , RAM «».
, â , , - .