2

ウィキペディアのサイトによると:

http://en.wikipedia.org/wiki/Volatile_variable

サンプルコードをラップトップでテストするためにコピーしましたが、2 つに違いはありません! ここに私のGCCバージョン情報があります:

i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Cソースコードは

/* volatile_var.c */
#include <stdio.h>
int main() {
        /* in no_volatile_var.c there is no volatile here */
        volatile int a = 10, b = 100, c = 0, d = 0;
        printf("%d\n", a + b);

        a = b;
        c = b;
        d = b;

        printf("%d\n", c + d);
        printf("%d\n", a);
        return 0;
}

no_volatile_var.c と volatile_var.c の両方をコンパイルしました

gcc -S *.c

しかし、アウトは同じです

    .section    __TEXT,__text,regular,pure_instructions
    .globl  _main
    .align  4, 0x90
_main:
Leh_func_begin1:
    pushq   %rbp
Ltmp0:
    movq    %rsp, %rbp
Ltmp1:
    subq    $32, %rsp
Ltmp2:
    movl    $10, -12(%rbp)
    movl    $100, -16(%rbp)
    movl    $0, -20(%rbp)
    movl    $0, -24(%rbp)
    movl    -12(%rbp), %eax
    movl    -16(%rbp), %ecx
    addl    %ecx, %eax
    xorb    %cl, %cl
    leaq    L_.str(%rip), %rdx
    movq    %rdx, %rdi
    movl    %eax, %esi
    movb    %cl, %al
    callq   _printf
    movl    -16(%rbp), %ecx
    movl    %ecx, -12(%rbp)
    movl    -16(%rbp), %ecx
    movl    %ecx, -20(%rbp)
    movl    -16(%rbp), %ecx
    movl    %ecx, -24(%rbp)
    movl    -20(%rbp), %ecx
    movl    -24(%rbp), %edx
    addl    %edx, %ecx
    xorb    %dl, %dl
    leaq    L_.str(%rip), %rdi
    movl    %ecx, %esi
    movb    %dl, %al
    callq   _printf
    movl    -12(%rbp), %ecx
    xorb    %dl, %dl
    leaq    L_.str(%rip), %rdi
    movl    %ecx, %esi
    movb    %dl, %al
    callq   _printf
    movl    $0, -8(%rbp)
    movl    -8(%rbp), %eax
    movl    %eax, -4(%rbp)
    movl    -4(%rbp), %eax
    addq    $32, %rsp
    popq    %rbp
    ret
Leh_func_end1:

    .section    __TEXT,__cstring,cstring_literals
L_.str:
    .asciz   "%d\n"

    .section    __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
EH_frame0:
Lsection_eh_frame:
Leh_frame_common:
Lset0 = Leh_frame_common_end-Leh_frame_common_begin
    .long   Lset0
Leh_frame_common_begin:
    .long   0
    .byte   1
    .asciz   "zR"
    .byte   1
    .byte   120
    .byte   16
    .byte   1
    .byte   16
    .byte   12
    .byte   7
    .byte   8
    .byte   144
    .byte   1
    .align  3
Leh_frame_common_end:
    .globl  _main.eh
_main.eh:
Lset1 = Leh_frame_end1-Leh_frame_begin1
    .long   Lset1
Leh_frame_begin1:
Lset2 = Leh_frame_begin1-Leh_frame_common
    .long   Lset2
Ltmp3:
    .quad   Leh_func_begin1-Ltmp3
Lset3 = Leh_func_end1-Leh_func_begin1
    .quad   Lset3
    .byte   0
    .byte   4
Lset4 = Ltmp0-Leh_func_begin1
    .long   Lset4
    .byte   14
    .byte   16
    .byte   134
    .byte   2
    .byte   4
Lset5 = Ltmp1-Ltmp0
    .long   Lset5
    .byte   13
    .byte   6
    .align  3
Leh_frame_end1:


.subsections_via_symbols

Wikiの説明によると、違いがあり、揮発性版は不揮発性版よりも大きくなるはずです。それらをバイナリにコンパイルしたところ、サイズも同じであることがわかりました。

質問:

  • 私のllvm-gccが原因ですか?(後でLinuxでこれらのコードをテストします)、またはWikiの説明はエラーですか?
  • どちらも同じバイナリ コードをコンパイルしたため (単純にサイズに応じて)、出力結果は同じです。しかし、Wiki の説明によると、この 2 つは異なる画面出力を出力しますか?

アップデート

この質問はウィキペディアの最適化設定の誤りによるもので、タイトルの内容とは関係ありません。この質問を閉じるべきですか?

4

3 に答える 3

5

を使用gcc -O3して最適化をオンにすると、違いがわかるはずです。

于 2012-09-05T15:53:05.247 に答える
4

volatile キーワードは、外部スレッドがいつでもこの変数を変更する可能性があることをコンパイラに知らせるための単なるヒントです。そのため、これが起こらないという前提に基づく最適化には注意する必要があります。ただし、アプリケーションには他のスレッドがないため、別の方法で処理する理由はありません。

より高い最適化設定 (-O3 コマンド ライン パラメーター) を使用してプログラムをコンパイルすることもできます。これにより、揮発性バージョンでは禁止されている非揮発性バージョンでコンパイラーが最適化を実行する可能性があります。

于 2012-09-05T15:52:48.893 に答える
0

variable を volatile として宣言すると、コンパイラは最適化を実行できません。

于 2012-09-05T17:01:36.423 に答える