GCCのいくつかの特性
33546 ワード
文字列の表示形式
gccがサポートする文字列の表現形式
「xxx」「xxx」「xxx」は、この3つの文字列を1つに連結し、最後の文字列の末尾に「0」を追加するだけで、各文字列間のスペース記号も無視します.
attribute
_attribute__実はgcc独自の構文で、関数属性(Function Attribute)、変数属性(Variable Attribute)、タイプ属性(Type Attribute)を設定するための構文です
構文
構造タイプのプロパティ aligned整列 packedをpackedで修飾すると、1バイト整列 になる.
関数プロパティ(Function Attribute) alias別名weak 申明cpu_mmc_initは_def_mmc_initの別名 cpu_mmc_Initが定義されていない場合は、2__を使用します.def_mmc_init、定義があればcpu_を使用しますmmc_init自体. __def_mmc_Init関数は必ず定義されています. weakプロパティを指定:cpu_でもmmc_init関数は定義されていません.cpu_を呼び出します.mmc_Initコンパイラもエラーを報告しない weakは一般的にalias属性と連用されます. unusedは、この変数または関数が使用されていない場合でも警告情報を出力しないことを指定します. section指定リンクsection この関数または変数の最後のリンクを指定します. リンクスクリプトで使用されるSection名は、実は変数の形式であり、定義する必要はなく、直接使用することができます.つまり、接続スクリプトでセグメント名 を自由に使用することができます.デフォルトでsection属性が指定する場合、初期化されていれば格納.dataセグメント;さもないと預けます.bssセグメント.sectionプロパティを指定すると、初期化するかどうかにかかわらず、指定したセグメントが格納されます. noreturnの主な機能は、コンパイラに呼び出されたことを伝えるために使用されます.attribute__(noreturn)の関数の後、制御はcaller に戻らない. noinline always_inline
noinline:強制的にインラインしません.1つの関数は、コード量が少ない場合、-O 3最適化スイッチを使用すると、gccがこの関数を強制的にインライン(inline)する可能性があります.
always_义齿インラインと定義してもすべてインラインされるとは限らないので、インラインは最後にgccコンパイラによって決定されます. pure pureは、関数が戻り値を除いて、他の(例えばグローバル変数、ポインタ)によって関数の外部に影響を及ぼさないことを示す.const と同様
パラメータが同じ場合、コンパイラは最適化され、キャッシュがパラメータとして使用される可能性があります. const定数最適化const attributeはコンパイラに最適化させる.const関数はより厳密です_pure関数 入力パラメータは定数であり、戻り値は同じであるため、複数回呼び出すときにコンパイラが最適化し、 を1回実行する. pure/const関数は読むしかなく、書くことができず、printなどをすることができません. constructor/destructor main関数の前後で を実行
関数がconstructorプロパティに設定されている場合、main()関数が実行される前に自動的に実行されます.同様に、関数がdestructorプロパティに設定されている場合、main()関数の実行後またはexit()が呼び出された後に自動的に実行されます. format検査パラメータ attribute((format(printf,m,n))attribute((format(scanf,m,n))format属性はコンパイラに教え、printf,scanf,strftimeまたはstrfmonのパラメータテーブルフォーマット規則に従って関数のパラメータを検査する
m:いくつかのパラメータはフォーマット文字列(format string);n:パラメータセットの最初のパラメータ、すなわちパラメータ「...」の最初のパラメータは、関数パラメータの総数で何番目に並んでいますか.
ゼロ長配列
役割:小さな内蔵を防止するには、構造体に長さの動的な文字列を格納する必要があります.たとえば、構造体に名前を格納しますが、この名前の長さは不明です.
ぶんしき
括弧でのループ、ローカル変数などの使用
標準Cでは、次のマクロに対応して副作用が発生します.
typeof取得タイプ
typeof(x)文はxのタイプを得ることができる
チェックの種類
チェック_xと_yのタイプが一致しているかどうか、2つの異なるポインタタイプが比較操作を行うと、コンパイラにコンパイル警告が発生し、この2つの値のタイプが異なることを示します.
範囲拡張switch...case...と配列 switch …case… 配列
__ビルディング関数判断呼び出しアドレス_builtin_return_address
現在の関数または呼び出し元の戻りアドレスを返します.パラメータLEVELは、0が現在の関数の戻りアドレス、1が現在の関数の呼び出し元の戻りアドレスなどの呼び出しスタックの段数を指定します.コンパイル定数検出_builtin_constant_p(EXP)は、1つの値がコンパイル時定数であるか否かを判断し、パラメータEXPの値が定数である場合、関数は1を返し、そうでない場合は0を返す. ブランチ予測プロンプトのコンパイル_builtin_expect(EXP,C)は、コンパイラに分岐予測情報を提供するために使用され、その戻り値は整数式EXPの値であり、Cの値はコンパイル時定数でなければならない.
可能性が高いのは前に置く
gccがサポートする文字列の表現形式
「xxx」「xxx」「xxx」は、この3つの文字列を1つに連結し、最後の文字列の末尾に「0」を追加するだけで、各文字列間のスペース記号も無視します.
attribute
_attribute__実はgcc独自の構文で、関数属性(Function Attribute)、変数属性(Variable Attribute)、タイプ属性(Type Attribute)を設定するための構文です
構文
attribute (parameter)
int a __attribute__ ((xxxxx));
構造タイプのプロパティ
struct info{
.....
} __attribute__ ((xxxxx)) sb;
// struct fd
struct fd{
...
}__sttribute__ ((align(4))) fd;
typedef struct {
char version;
int16_t sid;
int32_t len;
int64_t time;
}__attribute__ ((packed)) Header;
関数プロパティ(Function Attribute)
noreturn
noinline
always_inline
pure
const
nothrow
sentinel
format
format_arg
no_instrument_function
section
constructor
destructor
used
unused
deprecated
weak
malloc
alias
warn_unused_result
nonnull
weak , alias
//
int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
static void func(void) __attribute__((unused));
static void func(int a,int b __attribute__((unused)),int c);
//__init
#define __init __attribute__ ((__section__ (".init.text"))) __cold
//__initdata
#define __initdata __attribute__ (( __section__ (".init.data")))
//__exitdata
#define __exitdata __attribute__ (( __section__ (".exit.data")))
[23] .data PROGBITS 0000000000600900 00000900
0000000000000004 0000000000000000 WA 0 0 4
[24] .init.data PROGBITS 0000000000600904 00000904
0000000000000018 0000000000000000 WA 0 0 4
[25] .bss NOBITS 0000000000600920 0000091c
0000000000000010 0000000000000000 WA 0 0 8
void __attribute__((noreturn)) die(void);
inline int add(int a, int b) __attribute__((always_inline));
inline int add(int a, int b) __attribute__((noinline));
noinline:強制的にインラインしません.1つの関数は、コード量が少ない場合、-O 3最適化スイッチを使用すると、gccがこの関数を強制的にインライン(inline)する可能性があります.
always_义齿インラインと定義してもすべてインラインされるとは限らないので、インラインは最後にgccコンパイラによって決定されます.
#define __purefunc __attribute__((pure))
int memcmp(const void *, const void *, size_t) __purefunc;
extern int atoi(const char*) __purefunc
パラメータが同じ場合、コンパイラは最適化され、キャッシュがパラメータとして使用される可能性があります.
char *x = calloc(1, 8);
char *y = calloc(1, 8);
if (memcmp(x, y, 8) > 0)
printf("x > y
");
// , , 。
x[1] = 'a';
if (memcmp(x, y, 8) > 0)
printf("x > y
");
for(int i = 0; i < fibonacci(100); ++i)
{
...
}
,
for(int i = 0,end = fibonacci(100); i < end; ++i)
{
...
}
//
int output() __attribute__((const));
int output()
{
std::cout << "lol | ";
return 1;
}
関数がconstructorプロパティに設定されている場合、main()関数が実行される前に自動的に実行されます.同様に、関数がdestructorプロパティに設定されている場合、main()関数の実行後またはexit()が呼び出された後に自動的に実行されます.
__attribute__((constructor)) void before_main() {
printf("--- %s
", __func__);
}
__attribute__((destructor)) void after_main() {
printf("--- %s
", __func__);
}
m:いくつかのパラメータはフォーマット文字列(format string);n:パラメータセットの最初のパラメータ、すなわちパラメータ「...」の最初のパラメータは、関数パラメータの総数で何番目に並んでいますか.
//m=2;n=3
extern void myprint(int l,const char *format,...) __attribute__((format(printf,2,3)));
ゼロ長配列
役割:小さな内蔵を防止するには、構造体に長さの動的な文字列を格納する必要があります.たとえば、構造体に名前を格納しますが、この名前の長さは不明です.
#include
#include
#include
struct node{
int num;
int data;
char name[0]; // [0]
};
char test_name[] = "testname";
int main(void)
{
struct node *test_node;
int length = strlen(test_name);
// malloc()
test_node = (struct node*)malloc(sizeof(struct node)+length);
//strncpy((char *)test_node+1, test_name, length);
strncpy(test_node->name, test_name, length);
printf("sizeof(struct node) = %d
", sizeof(struct node));
printf("num addr:%p
", &(test_node->num));
printf("data addr:%p
", &(test_node->data));
printf("name addr:%p
", test_node->name);
printf("test_node+1 addr:%p
", test_node+1);
printf("name = %s
", test_node->name);
printf("name[0] = %c
", test_node->name[0]);
printf("name[%d] = %c
", lenght-1, test_node->name[length-1]);
free(test_node);
}
//result
sizeof(struct node) = 8
num addr:0x1574010
data addr:0x1574014
name addr:0x1574018
test_node+1 addr:0x1574018
name = testname
name[0] = t
name[7] = e
ぶんしき
括弧でのループ、ローカル変数などの使用
#define min_t(type,x,y) \
({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
int ia, ib, mini;
float fa, fb, minf;
// __x __y , 。
mini = min_t(int, ia, ib);
minf = min_t(float, fa, fb);
標準Cでは、次のマクロに対応して副作用が発生します.
#define min(x,y) ((x) < (y) ? (x) : (y)) min(++ia,++ib) ((++ia) < (++ib) ? (++ia): (++ib)), 。
typeof取得タイプ
typeof(x)文はxのタイプを得ることができる
#define min(x,y) ({ \
const typeof(x) _x = (x); \
const typeof(y) _y = (y); \
(void) (&_x == &_y); \
_x < _y ? _x : _y; })
チェックの種類
(void) (&_x == &_y)
チェック_xと_yのタイプが一致しているかどうか、2つの異なるポインタタイプが比較操作を行うと、コンパイラにコンパイル警告が発生し、この2つの値のタイプが異なることを示します.
範囲拡張switch...case...と配列
static int sd_major(int major_idx)
{
switch (major_idx) {
case 0:
return SCSI_DISK0_MAJOR;
case 1 ... 7:
return SCSI_DISK1_MAJOR + major_idx - 1;
case 8 ... 15:
return SCSI_DISK8_MAJOR + major_idx - 8;
default:
BUG();
return 0; /* shut up gcc */
}
}
/* Vector of locks used for various atomic operations */
spinlock_t cris_atomic_locks[] = { [0 ... LOCK_COUNT - 1] = SPIN_LOCK_UNLOCKED};
int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };
__ビルディング関数
__builtin_return_address (LEVEL) //LEVEL
現在の関数または呼び出し元の戻りアドレスを返します.パラメータLEVELは、0が現在の関数の戻りアドレス、1が現在の関数の呼び出し元の戻りアドレスなどの呼び出しスタックの段数を指定します.
#define roundup_pow_of_two(n) \
( \
__builtin_constant_p(n) ? ( \
(n == 1) ? 1 : \
(1UL << (ilog2((n) - 1) + 1)) \
) : \
__roundup_pow_of_two(n) \
)
// if
#define likely(x) __builtin_expect(!!(x), 1) // if
#define unlikely(x) __builtin_expect(!!(x), 0) // else
if (likely(a>b)) {
fun1();
}
可能性が高いのは前に置く