関数指定子
From cppreference.com
関数の宣言で使用されます。
| このセクションは未完成です 理由: 2ページに分割 |
inline(C99以降) - 関数を「インライン化」し、その呼び出しを可能な限り高速化するようコンパイラに提案します。_Noreturn(C11以降) - 関数が呼び出し元に戻らないことを指定します。
目次 |
[編集] 構文
| inline 関数宣言 | |||||||||
| _Noreturn 関数宣言 | |||||||||
[編集] 説明
[編集] inline (C99以降)
inlineキーワードは、最適化を実行するようコンパイラに与えるヒントです。コンパイラはこの要求を無視する自由があります。
コンパイラが関数をインライン化する場合、その関数のすべての呼び出しを実際の本体に置き換えます(呼び出しを生成せずに)。これにより、関数呼び出しによって生じる余分なオーバーヘッド(スタックへのデータ配置と結果の取得)を回避できますが、関数のコードが複数回繰り返される必要があるため、実行可能ファイルが大きくなる可能性があります。結果は関数形式マクロに似ています。
関数の本体は現在の翻訳単位から可視でなければなりません。これにより、inlineキーワードはヘッダファイル内に関数を実装するために、つまりコンパイルしてリンクする必要があるソースファイルを持たずに実装するために必要になります。
[編集] inline の例
インライン化をオフにすると、実行時間は約1.70秒です。インライン化をオンにすると、実行時間は1秒未満です。
このコードを実行
/* inline int sum(int a, int b) { return (a + b); } int c = sum(1, 4); // If the compiler inlines the function the compiled code will be the same as writing: int c = 1 + 4; */ #include <stdio.h> #include <stdlib.h> #include <time.h> /* int sum (int a, int b) __attribute__ ((noinline)); */ static inline int sum (int a, int b) { return a+b; } int main(void) { const int SIZE = 100000; int X[SIZE],Y[SIZE],A[SIZE]; int i,j; for (i=0;i<SIZE;++i) { X[i] = rand(); Y[i] = rand(); } clock_t t = clock(); /* start clock */ for (i=0;i<5000;++i) { for (j=0;j<SIZE;++j) A[j] = sum(X[j],Y[j]); } t = clock()-t; /* stop clock */ printf("Time used: %f seconds\n", ((float)t)/CLOCKS_PER_SEC); printf("%d\n", A[0]); return EXIT_SUCCESS; }
実行結果の例
Time used: 0.750000 seconds -1643747027
[編集] _Noreturn (C11以降)
_Noreturnキーワードは、それに続く関数が呼び出し元の関数に戻らないことを示します。_Noreturnで宣言された関数が値を返そうとすると、コンパイラは通常、警告を生成します。
以下の例では、stop_now()関数が呼び出され、これによりプログラムは即座に終了します(SIGABRTシグナルが捕捉されない限り)。stop_now()の呼び出しの後にあるprintf()とreturn EXIT_SUCCESS;を含むコードは決して実行されず、実行はstop_now()が呼び出されたmain()関数に戻ることはありません。
[編集] _Noreturn の例
このコードを実行
#include <stdlib.h> #include <stdio.h> _Noreturn void stop_now() { abort(); } int main(void) { printf("Preparing to stop...\n"); stop_now(); printf("This code is never executed.\n"); return EXIT_SUCCESS; }
出力
Preparing to stop... Abort