2016幎にCを曞くためのヒント


蚀語Cが歊噚だった堎合

著者からこの蚘事の抂芁は2015幎の初めに掲茉されたしたが、資料の出版には至りたせんでした。 最埌に、私のラむティングデスクの匕き出しには、䞊蚘の「ドラフト」のメリットはないず刀断したので、元の圢で泚意を喚起したす。 テキストで倉曎されおいるのは、2015幎から2016幎たでの幎のみです。

そしお、必芁な修正、説明、たたは苊情に぀いおのコメントをい぀でも喜んで聞きたす。

だから蚘事...

Cでのプログラミングの最初のルヌルは、他のツヌルで問題がなければ䜿甚しないこずです。

別の方法を芋぀けるこずができないずきは、プログラマヌの珟代の戒めを思い出しおください。

Cプログラミング蚀語は1970幎代初期から存圚しおいたした。 専門家は進化のさたざたな段階で「Cを研究」しなければならず、芪しい関係者はしばしば行き止たりに至りたした。 したがっお、この蚀語のアルゎリズムを䜿甚した最初の経隓により、さたざたなプログラマヌがワヌルドCに぀いお独自の考えを持っおいたした。

Cでのプログラミングに盎面しお、「80幎代/ 90幎代に孊んだ真実」のレベルで立ち埀生しないこずが非垞に重芁です。

この蚘事を読んだ堎合、おそらく最新のプラットフォヌムで䜜業しおおり、珟圚の暙準を順守しおいるため、叀い゜フトりェアに関する無限の芏則を参照する必芁はありたせん。 個々の䌁業がせいぜい20幎前のシステムをアップグレヌドするこずを気にしなかったため、叀代の基準を氞続させるこずは無意味です。

はじめに


暙準C99ここではC99-「1999幎以降のプログラミング暙準」、C11-「2011幎以降のプログラミング暙準」、぀たり11> 99。

clang, default


最適化


-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 LTO
GCC LTO

2016幎たでに、 clang gccは補助LTOの䜜成を凊理したした。これは、オブゞェクトをコンパむルし、最終的にラむブラリ/プログラム芁玠をマヌゞするずきにコマンドのリストに-fltoを远加するこずで利甚できたす。 ただし、 LTOただ目ず目が必芁です。 堎合によっおは、プログラムが盎接実行されないが远加のラむブラリヌを介しおコヌドを䜿甚する堎合、 LTOは察応する関数たたはコヌドを陀倖できたす。これは、䞀般的な分析の過皋で、ナヌティリティが䜿甚されおいないこずを怜出するためです。぀たり、補品の最終バヌゞョンでは䞍芁です。

Arch
-march=native

コンパむラヌにプロセッサヌのすべおの機胜を䜿甚させ、芚えおおいおくださいパフォヌマンステストず回垰テストは重芁です異なるコンパむラヌおよび/たたはそれらのバヌゞョンの結果の比范分析が埌に続きたす。それらの助けを借りお、最適化芁玠に悪圱響がないこずを確認できるためです。

-msse2 -msse4.2は、他の開発者が甚意したオプションを䜿甚する堎合に必芁になる堎合がありたす。

コヌド生成


皮類

新しいコヌドでchar, int, short, long unsignedようなものを芋぀けた堎合、ここに゚ラヌがありたす。
最新のプログラムでは、 #include <stdint.h>を指定しおから、暙準のデヌタ型を遞択する必芁がありたす。
詳现な説明は、 stdint.h仕様にありたす。
最も䞀般的な暙準デヌタ型には次のものがありたす。


泚意しおくださいこれ以䞊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のアドバむスに埓っお、垞に適切なタむプポむンタヌを䜿甚しおください。

このリストには以䞋が含たれたすもちろん、これは短い抜粋にすぎたせん


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; } 



:
 /*  : * - 'true'  newLen > currentLen     * -    'true'     ,      '*_grow' * - 'false'  newLen <= currentLen */ 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; /*   , * 'true'     ,       */ 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) .

:



, , , .

, calloc() , :

Benchmarking fun with calloc() and zero pages (2007)
Copy-on-write in virtual memory management

2016 - calloc() ( , 64 , , , ). « » , « », .

: calloc() – , . calloc() realloc() , . . realloc() , memset() .

memset ( )

memset (ptr, 0, len, () ( , ).
memset() — , , ( {0} , ).

おわりに


, , . , , , , , RAM «».

, — , , - .

Source: https://habr.com/ru/post/J275685/


All Articles