2

以下の関数の分解を調べながら、

void * malloc_float_align(size_t n, unsigned int a, float *& dizi)
    {
        void * adres=NULL;
        void * adres2=NULL;
        adres=malloc(n*sizeof(float)+a);
        size_t adr=(size_t)adres;
        size_t adr2=adr+a-(adr&(a-1u));
        adres2=(void * ) adr2;
        dizi=(float *)adres2;
        return adres;
    }

組み込み関数は、inline最適化フラグが設定されていてもインライン化されません。

; Line 26
$LN4:
    push    rbx
    sub rsp, 32                 ; 00000020H
; Line 29
    mov ecx, 160                ; 000000a0H
    mov rbx, r8
    call    QWORD PTR __imp_malloc <------this is not inlined
; Line 31
    mov rcx, rax
; Line 33
    mov rdx, rax
    and ecx, 31
    sub rdx, rcx
    add rdx, 32                 ; 00000020H
    mov QWORD PTR [rbx], rdx
; Line 35
    add rsp, 32                 ; 00000020H
    pop rbx
    ret 0

質問:これは のような関数の必須プロパティmallocですか? それを検査する方法(または strcmp/new/free/delete のような他の関数)をインライン化できますか? これは禁止されていますか?

4

4 に答える 4

3

通常、コンパイラは、コンパイル中に使用可能なソース コードがある場合 (つまり、関数が単なるプロトタイプ宣言ではなく定義されている場合)、関数をインライン化します。

ただし、この場合、関数 ( malloc) は DLL 内にあるため、コードのコンパイル中にコンパイラがソース コードを利用できないことは明らかです。malloc(など)とは何の関係もありません。ただし、mallocソースコードが利用可能であってもインライン化できないため、かなり大きな関数であるため(少なくともそうであることが多い)、とにかくインライン化されない可能性があります。

Visual Studio を使用している場合、ランタイム ライブラリのソース コードは Visual Studio パッケージで提供されているため、ほぼ確実に見つけることができます。

(システム内の多くの異なるプログラムが同じ関数を使用するため、C ランタイム関数は DLL 内にあります。そのため、機能のすべての「ユーザー」に対して 1 回ロードされる DLL にそれらを配置すると、すべてのサイズを大幅に節約できます。システム内のコード. malloc はおそらく数百バイトにすぎませんが, 関数のようなものprintfは実行可能ファイルのサイズに 5-25KB を簡単に追加できます. これに の「ユーザー」の数を掛けると,printfおそらく数百キロバイトになります. 「保存された」その1つの関数からだけ-そしてもちろん、、、、、、などの他のすべての関数はfopenすべて、fclose全体のサイズにそれぞれ少しずつ追加されます)malloccallocfree

于 2013-07-28T20:11:43.023 に答える
1

AC コンパイラはインラインmalloc化できます (または、例でわかるように、その一部) が、インライン化する必要はありません。使用するヒューリスティックは文書化する必要はなく、通常は非常に複雑ですが、コードが肥大化する可能性があるため、通常は短い関数のみがインライン化されます。

于 2013-07-28T20:10:25.107 に答える
1

mallocおよびフレンドはランタイム ライブラリに実装されるため、インライン化には使用できません。そのためには、ヘッダー ファイルに実装を含める必要があります。

それらの逆アセンブリを確認したい場合は、デバッガーを使用してそれらにステップインできます。または、使用しているコンパイラとランタイムによっては、ソース コードが利用できる場合があります。たとえば、gcc と msvc の両方で使用できます。

于 2013-07-28T20:10:26.253 に答える
1

et alのインライン化を止める主な理由malloc()は、それらの複雑さです — そして、関数のインライン定義が提供されていないという明らかな事実です。さらに、さまざまな時期にさまざまなバージョンの関数が必要になる場合があります。ツールが機能するのは難しく(面倒です)valgrind、コードがインラインで展開されている場合、関数のデバッグバージョンを使用するように手配できませんでした。

于 2013-07-28T20:10:27.123 に答える