2012-01-03 9 views
20

オブジェクト指向言語(C++)では、グローバルオブジェクトまたはクラスの静的オブジェクトを使用して、main()より前にコードを実行し、コンストラクタに必要なコードを実行させることができます。main()の前にコードを実行

Cでこれを行う方法はありますか?私は解決しようとしている特定の問題はありません、私はちょうど興味があります。これは、ライブラリを自動的に初期化するのに便利です。

+0

http://stackoverflow.com/questions/949890/how-can-i-perform-pre-main-in-itialization-in-cc-with-avr-gcc – stacker

+0

@stacker - あなたが参照する質問は、 Arduino環境。とにかく、そこに答えが役立つかもしれません。 – mouviciel

答えて

10

__attribute__を使用する方法がありますが、これらはコンパイラ固有のもので、ではないは本当に移植可能です。一方、C言語は起動モジュール/ライブラリを提供しません。

論理的には、main()は、OSによって呼び出される関数です。しかし、main()を呼び出す前に、OSはstart-upモジュールと呼ばれる別の関数を呼び出して、さまざまな環境変数を設定し、静的変数を初期化(初期化されていない)し、スタックフレーム(起動レコード)を構築し、スタックポインタをスタック領域の開始タスクは、main()を呼び出す前に行う必要があります。

上記の作業を行うためのOSがない、または最小限のOSがある組み込みシステム用のコードを作成する場合は、コンパイラに依存するこれらのオプションを調べる必要があります。 GCC、Turbo-C、Microsoft Cコンパイラ以外にも、特定のハードウェアマシン(8086マシン)にコードを追加する機能があります。

IOWでは、起動モジュールはプログラマ向けではありません。

+0

間違っていると、 'main'はOSが呼び出す最初の関数ではありません。あなたは[crt0](https://en.wikipedia.org/wiki/Crt0)について聞いたことがありますか? '_start'は常に' main'の前に呼び出され、Windowsでは 'WinMain'も' main'の前に呼び出されます。 –

0

グローバル変数は初期化できますが、これらの初期化では関数を呼び出すことはできません。

1

いいえ、あなたはCでそれを行うことはできません。私は、実際には "main()より前に実行するコード"をC++でも得ることができないと主張します。はい、のように表示されますが、main()の前にはmain()が表示されます。

これで値を初期化することができます。あらかじめ設定された状態の変数を持つこともできますが、それは同じことではありません。

+3

3.6.2/3( "これは、初期化されるオブジェクトと同じ変換単位で定義された関数またはオブジェクトの最初の使用前に行われる)"、同じTU内の名前空間スコープのオブジェクトは、 'main'は最初の' main'文の前に初期化されます。なぜなら、 'main' *は同じTUの中の関数なのですから。標準では、 'main'の関数本体の中から、他の文の前に、そのinitコードを呼び出すかどうか、またはinitを実行する他の関数があるかどうかは気にしません。 –

4

gccを使用するには、コンストラクタ関数の属性を使用します(例:

__attribute__ ((__constructor__)) 
void foo(void) { 
     ... 
} 

これはmainの前にfooを呼び出します。

注:これはおそらく他のコンパイラには移植できません。

13

__attribute__ ((constructor))とすることができます。私はgccclangの両方で次の例をテストしました。つまり、それはではなく、言語の一部です。

#include <stdio.h> 

void __attribute__ ((constructor)) premain() 
{ 
    printf("premain()\n"); 
} 

int main(int argc, char *argv[]) 
{ 
    printf("main()\n"); 
    return 0; 
} 

それは次の処理を行います。任意の標準規格に準拠した方法で

$ ./test 
premain() 
main() 
0

ないが、あなたがお使いのオペレーティングシステムは、バイナリイメージをロードし、アプリケーションのメイン機能を呼び出したときに、本当に何が起こるかに掘る必要があります!

0

mainが実行された後に実行できる機能を指定する移植可能な方法があります。さらに

  1. atexit()

  2. at_quick_exit()

thisリンクをたどると、C++での初期化の様々なタイプについて - あなたは(メインの前にコードを実行するために有用である可能性がある)と呼ばれています。

+0

さらに、この[link](http://en.cppreference.com/w/cpp/language/initialization)と、C++でのさまざまな初期化方法について説明します。これは、main()を呼び出す前にコードを実行すると便利です。と呼ばれる。 –

+0

問題は、mainの前にコードを呼び出すことでした。mainやC++の後にコードを呼び出さないようにしました。 –

関連する問題