2016-08-14 92 views
3

正如你可以在下面的代碼中看到的,我介紹了一個嵌套函數內main()如何禁用GNU C擴展?

#include <stdio.h> 

int main(){ 
int a=5; 
printf("%d\n",a); 
{ 
    int a=10; 
    printf("%d\n",a); 
} 
printf("%d\n",a); 

//Nested function 
int main(int a){ 
if(a>0)printf("%d\n",a--); 
return 0; 
} 

main(7); 
return 0; 
} 

至於我能理解我用-std=c99標誌GCC爲「禁用」的不必要的擴展,但我沒有得到任何錯誤。

gcc temp3.c -std=c99 -o temp3.out

哪裏有我犯的錯?

+4

添加'-pedantic -Werror'應該可以解決這個問題。 –

+0

那麼-std = c99標誌有什麼用? –

+0

'-std = c99'標誌禁用GCC認爲應該禁用的GNU擴展 - 例如POSIX版本等。請參閱[C語言選項](https://gcc.gnu.org/onlinedocs/gcc/C- Dialect-Options.html#C-Dialect-Options)來表示'-std ='的含義;有關'-pedantic'的含義,請參閱[警告選項](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#Warning-Options)。 –

回答

7
  • -pedantic-Werror添加到命令行。

在Mac OS X 10.11.6使用GCC 6.1.0,在文件ped73.c你的原代碼和我的默認編譯選項,我得到:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes \ 
>  -Wold-style-definition ped73.c -o ped73 
ped73.c:3:5: error: function declaration isn’t a prototype [-Werror=strict-prototypes] 
int main(){ 
    ^~~~ 
ped73.c: In function ‘main’: 
ped73.c:3:5: error: old-style function definition [-Werror=old-style-definition] 
ped73.c:13:6: error: ‘main’ takes only zero or two arguments [-Werror=main] 
    int main(int a){ 
     ^~~~ 
ped73.c:13:6: error: ‘main’ is normally a non-static function [-Werror=main] 
$ 

重命名嵌套函數nested和使用int main(void),我得到:

$ gcc -O3 -g-std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes 
>  -Wold-style-definition -o ped73 
$ 

使用額外的選項-pedantic我得到:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes \ 
>  -Wold-style-definition -pedantic ped73.c -o ped73 
ped73.c: In function ‘main’: 
ped73.c:13:2: error: ISO C forbids nested functions [-Werror=pedantic] 
    int nested(int a){ 
    ^~~ 
cc1: all warnings being treated as errors 
$ 

那麼什麼的-std=c99點?

-std=c99標誌禁用GCC自以爲應該被禁用的GNU擴展 - 如POSIX版本等爲-std=意義,請參見C Dialect Options;有關-pedantic的含義,請參閱Warning Options。通過嚴格的ISO C和ISO C++要求

-Wpedantic
-pedantic

發行所有的警告;拒絕所有使用禁止擴展的程序,以及其他一些不遵循ISO C和ISO C++的程序。對於ISO C,遵循所使用的任何-std選項指定的ISO C標準版本。

有效的ISO C和ISO C++程序應該在有或沒有此選項的情況下正確編譯(儘管極少數需要-ansi-std選項指定所需版本的ISO C)。但是,如果沒有這個選項,也支持某些GNU擴展和傳統的C和C++特性。有了這個選項,他們被拒絕。

-Wpedantic不會導致使用名稱以__開頭和結尾的替代關鍵字的警告消息。在__extension__之後的表達式中,迂腐警告也被禁用。但是,只有系統頭文件應該使用這些轉義路由;應用程序應該避免它們。請參閱備用關鍵字。

一些用戶嘗試使用-Wantantic來檢查程序是否符合嚴格的ISO C標準。他們很快就發現它並沒有達到他們想要的水平:它找到了一些非ISO的做法,但不是所有的只有ISO C需要診斷的那些做法,以及其他一些診斷已經添加了的做法。

報告任何不符合ISO C的功能在某些情況下可能會有用,但需要大量的額外工作,並且與-Wantantic完全不同。我們不打算在不久的將來支持這種功能。

如果-std指定的標準表示C的GNU擴展方言,如'gnu90'或'gnu99',則存在相應的基本標準,GNU擴展方言所依據的ISO C版本。 -Wpedantic給出的警告在基本標準要求的地方給出。 (這種警告只適用於不在指定的GNU C方言中的功能是沒有意義的,因爲根據定義,C的GNU方言包括編譯器支持的所有功能,並且沒有任何可警告的內容。)


有多種問題,哪些GCC編譯器選項使用,包括:

毫無疑問,還有許多其他人可以添加到該列表。基本上,我使用的默認選項確保函數在使用之前被聲明(或者在使用函數之前被定義爲static函數),並且函數聲明具有完整的原型 - 沒有空括號() - 並使用-Wall-Wextra可以發現其他一些常規問題,包括格式字符串和printf()scanf()系列函數的參數之間的不匹配。

+0

這是我在將'-pedantic'添加到我的默認編譯字符串時偶然發現的。我發現它的唯一記錄是[** GCC **支持的語言標準](https://gcc.gnu.org/onlinedocs/gcc/Standards.html) –

+0

可能要強調並解釋您對' - 牆-Wextra'。這些會導致編譯器報告其默認情況下未配置的各種問題。並非所有這些都與避免gcc擴展有關,但它們擔心會指出錯誤(可疑轉換等),或者不能像其他編譯器那樣按預期工作。如果'-Werror'不會導致警告終止,則會採取「不接受觸發警告的代碼」的故意策略。 – Peter