簡體   English   中英

為什么微軟的C編譯器要function開頭的變量?

[英]Why does Microsoft's C compiler want the variables at the beginning of the function?

我目前正在編寫 C(不是 C++)。 微軟的 C 編譯器似乎要求在 function 之上聲明所有變量。

例如,以下代碼將不會通過編譯:

int foo(int x) {
    assert(x != 0);
    int y = 2 * x;
    return y;
}

編譯器在第三行報錯,說

error C2143: syntax error : missing ';' before 'type'

如果將代碼更改為如下所示,它將通過編譯:

int foo(int x) {
    int y;
    assert(x != 0);
    y = 2 * x;
    return y;
}

如果我將源文件名從.c更改為.cpp ,編譯也將通過。

我懷疑有一個選項可以關閉編譯器的嚴格性,但我還沒有找到它。 有人可以幫忙嗎?

提前致謝。

我正在使用 Visual Studio 2008 SP1 附帶的 cl.exe。

添加:

謝謝大家的回答。 看來我必須與 Microsoft 的 cl.exe 一起生活在 C89 中。

看起來它使用的是 C89 標准,它要求在任何代碼之前聲明所有變量。 您可以使用文字等初始化它們,但不能混合使用代碼和變量。

應該有一個編譯器標志可以在某處啟用 C99,這將使您獲得您習慣的行為。

編輯:快速谷歌搜索似乎不太希望啟用 C99。 您可能不得不使用 C89(還不錯)或找到更好的 C 編譯器(這會更好)。

Microsoft C 編譯器是 C89 編譯器,不再升級,標准 C99 沒有計划。 對於 C99 中的普通 C(變量不在塊開頭),請使用另一個編譯器或 C++ 擴展。

正如其他人所說,這只是MSC支持的C版本。 但是,如果您准備冒犯純粹主義者,您可以強制編譯器編譯為 C++。

這對純 C 幾乎沒有什么影響(有一些關於強制轉換 void* 指針和名稱裝飾更改的規則),但可能會給你一個有用的混合。 生成的代碼將大致相同 - 進行此更改不會導致效率的神奇損失(或增益)。

你沒有說你為什么熱衷於使用 C。

我不知道 C99,但對於早期版本的語言,局部變量必須在 { } 塊的開頭聲明。

您必須基於此錯誤使用的 C89 標准要求在開始執行任何塊中的語句之前聲明變量。

.cpp 擴展文件不會有這個問題,因為編譯器會將這些文件視為 C++ 文件,它沒有相同的限制。

您的斷言語句是代碼,因此您不能在此之后聲明變量(在同一塊/范圍內)。

從技術上講,您可以這樣做:

int foo(int x) {
    assert(x != 0);
    {
        int y = 2 * x;
        return y;
    }
}

但我不建議這樣做。

C90中,所有變量都必須在第一條語句之前聲明。 C99中情況並非如此。 我想你可以看看編譯器是否有 C99 的開關。

它使翻譯成匯編變得更容易。 當您進入 function 時,所有變量都被壓入堆棧,因此您不必擔心在其他任何地方進行操作。

同意關於 C 規范的評論。 請記住,C 是在計算機沒有大量 memory 的時候創建的。

解決這個問題的一種方法是確保可以從上到下一次讀取源文件(這也是使用 .h 文件的原因 -> 它們告訴代碼某些函數確實存在,但可能在第一次引用它們之后的某個地方)。

為在 scope 頂部聲明變量的代碼創建編譯器可能比為可以在任何地方聲明變量的代碼創建編譯器更容易。

遺憾的是,MS 沒有實現混合聲明和語句作為 C 編譯器的擴展(即使它默認關閉並且需要打開)。 我不確定,但我認為這是其他非 C99 C 編譯器中非常常見的擴展; 似乎我經常需要修復源代碼和示例才能在 MSVC 中編譯。

我認為這將相對容易實現,因為他們當然已經為 C++ 做到了。

C 規范要求在可執行代碼的第一行之前聲明所有變量。 編譯器遵守規范。 一些編譯器在這方面是寬松的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM