Cでの#pragma
の使用例は何ですか?
#pragma
は、マシン固有またはオペレーティングシステム固有のコンパイラディレクティブ用です。つまり、コンパイラに何かをしたり、オプションを設定したり、アクションを実行したり、デフォルトをオーバーライドしたりするように指示します。すべてのマシンとオペレーティングシステムに。
詳細については、 msdn を参照してください。
#pragma
は、Cで実装固有の何かを行うために使用されます。つまり、イデオロギー的に独断的ではなく、現在のコンテキストに対して実用的です。
私が定期的に使用しているのは#pragma pack(1)
で、埋め込みソリューションでメモリスペースをさらに絞り出そうとしています。そうしないと、8バイトのアライメントになってしまう構造の配列があります。
残念ながら、まだ#dogma
がありません。楽しそう ;)
通常、#pragmasはコンパイラに大きく依存しており、移植性がないため、可能であれば#pragmasの使用を避けようとします。それらを移植可能な方法で使用する場合は、すべてのプラグマを#if
/#endif
ペアで囲む必要があります。 GCCはプラグマの使用を推奨しておらず、他のコンパイラとの互換性のためにプラグマの一部のみを実際にサポートしています。 GCCには、他のコンパイラがプラグマを使用するのと同じことを行う他の方法があります。
たとえば、MSVCで構造がしっかりとパックされていること(つまり、メンバー間にパディングがないこと)を確認する方法は次のとおりです。
#pragma pack(Push, 1)
struct PackedStructure
{
char a;
int b;
short c;
};
#pragma pack(pop)
// sizeof(PackedStructure) == 7
GCCで同じことを行う方法は次のとおりです。
struct PackedStructure __attribute__((__packed__))
{
char a;
int b;
short c;
};
// sizeof(PackedStructure == 7)
GCCコードはより移植性があります。GCC以外のコンパイラを使用してコンパイルする場合、必要な作業はすべて
#define __attribute__(x)
一方、MSVCコードを移植する場合は、各プラグマを#if
/#endif
ペアで囲む必要があります。可愛くない。
#pragma once
をヘッダーファイルの先頭に配置すると、確実に1回だけ含まれます。 #pragma once
は標準C99ではありませんが、最新のコンパイラーのほとんどでサポートされていることに注意してください。
別の方法は、インクルードガードを使用することです(例:#ifndef MY_FILE #define MY_FILE ... #endif /* MY_FILE */
)
私が感じるものは#pragma
は、コードを特定の場所にしたい場合、たとえばISRが書き込まれている特定のアドレスからプログラムカウンターに読み取りたい状況の場合、ISRを指定できるディレクティブです#pragma vector=ADC12_VECTOR
を使用し、その後に割り込みrotines名とその説明が続く場所
プラグマは定義により実装固有であるため、コンパイラのドキュメントを参照することをお勧めします。たとえば、組み込みプロジェクトでは、さまざまなセクションでコードとデータを見つけたり、割り込みハンドラーを宣言したりするためにそれらを使用しました。すなわち:
#pragma code BANK1
#pragma data BANK2
#pragma INT3 TimerHandler
#pragma startup
は、メイン関数の前に関数を呼び出し、メイン関数の後に別の関数を呼び出すために使用されるディレクティブです。
#pragma startup func1
#pragma exit func2
ここで、func1
はmain
の前に実行され、func2
はその後に実行されます。
注:このコードはTurbo-Cコンパイラでのみ機能します。 GCCでこの機能を実現するには、次のようにfunc1
およびfunc2
を宣言できます。
void __attribute__((constructor)) func1();
void __attribute__((destructor)) func2();
これは、特定の機能をオンまたはオフにするために使用できるプリプロセッサディレクティブです。
#pragma startup
、#pragma exit
、および#pragma warn
の2つのタイプがあります。
#pragma startup
を使用すると、プログラムの起動時に呼び出される関数を指定できます。
#pragma exit
を使用すると、プログラムの終了時に呼び出される関数を指定できます。
#pragma warn
は、警告を抑制するかどうかをコンピューターに指示します。
他の多くの#pragma
スタイルを使用して、コンパイラを制御できます。
上記のすべての回答は、#pragma
の素晴らしい説明ですが、小さな例を追加したいと思いました。
simple OpenMP example
のいくつかの使用法を示す#pragma
を説明したい
OpenMp
briefly
は、マルチプラットフォームの共有メモリ並列プログラミングの実装です(それはmachine-specific
またはoperating-system-specific
と言えます)
例に行きましょう
#include <stdio.h>
#include <omp.h>// compile with: /openmp
int main() {
#pragma omp parallel num_threads(4)
{
int i = omp_get_thread_num();
printf_s("Hello from thread %d\n", i);
}
}
出力は
Hello from thread 0
Hello from thread 1
Hello from thread 2
Hello from thread 3
Note that the order of output can vary on different machines.
#pragma
が何をしたかを教えてください...
4つのスレッドでコードのブロックを実行するようにOSに指示します
これはmany many applications
の1つにすぎません。小さな#pragma
外部サンプルOpenMP
でごめんなさい
まとめると、#pragma
はコンパイラーに何かをするように指示します。使用方法は次のとおりです。
#pragma
は、コンパイラの警告を無視するために使用できます。たとえば、GCCを暗黙的な関数宣言について黙らせるには、次のように記述できます。
#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
libportable
の古いバージョンはこれを行います portably 。
#pragma once
は、ヘッダーファイルの先頭に書き込まれると、そのヘッダーファイルが1回含まれます。 libportable
checks プラグマワンスサポート用。