我想讓編譯器在每次出現宣告后拋出一個錯誤,因為這是我想要執行的編碼風格,但我也想用 -std=c99 進行編譯,因為我使用了一些特定的 c99 功能。
問題是,在 c99 中,宣告可以在代碼的任何地方被允許,而不僅僅是在塊的開頭。
看一下下面的程式:
// prog.c
#include <stdio.h>/span>
int main(void)
{
printf("hello world
")。)
int i = 0;
return 0;
如果我用gcc像這樣編譯這段代碼:
gcc -std=c99 -Werror=declaration-afterstatement prog.c
它拋出了以下錯誤:
prog.c: 在函式'main'中。
prog.c:6:9: error: ISO C90禁止混合宣告和代碼[-Werror=宣告-宣告后]
6 | int i = 0;
| ^~~
cc1:一些警告被當作錯誤處理
這是我在用clang編譯時希望得到的行為,但是clang的行為卻不一樣。
如果我用clang編譯相同的代碼,像這樣:
clang -std=c99 -Werror=declaration-afterstatement prog.c
它沒有拋出錯誤。
只有當我像這樣用clang編譯代碼時,才會拋出我想要的錯誤:
clang -std=c90 -Werror=declaration-afterstatement prog.c
prog.c:6:6: 錯誤。ISO C90禁止混合宣告和代碼 [-Werror,-Wdeclaration-after-statement]
int i = 0;
^
1 錯誤產生。
但這對我來說并不合適,因為我需要使用-std=c99。
在用clang編譯時,是否有可能將-Werror=declaration-after-statement與-std=c99一起強制使用?
uj5u.com熱心網友回復:
查看clang的源代碼,似乎不支持。
診斷器被定義在clang/include/clang/Basic/DiagnosticSemaKind.td
def ext_mixed_decls_code 。擴展<。
"ISO C90禁止混合宣告和代碼"> 。
InGroup<DiagGroup<"宣告-后宣告">>。
而它唯一的用法是在clang/lib/Sema/SemaStmt.cpp
StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
ArrayRef<Stmt *> Elts, bool isStmtExpr) {
const unsigned NumElts = Elts.size()。
//如果我們是在C89模式下,檢查我們在stmts后面沒有任何decls。 如果
//這樣,就發出一個擴展診斷。
if (!getLangOpts().C99 && !getLangOpts() .CPlusPlus) {
//注意,__extension__可以在decl.周圍。
unsigned i = 0;
///跳過所有宣告。
for (; i != NumElts && isa<DeclStmt> (Elts[i]); i)
/*empty*/。
//我們找到了串列或陳述句的末端。 掃描另一個declstmt.。
for (; i != NumElts && !isa<DeclStmt> (Elts[i]); i)
/*empty*/。
if (i != NumElts) {
Decl *D = *cast<DeclStmt> (Elts[i])->decl_begin();
Diag(D->getLocation(), diag::ext_mixed_decls_code); // <-- here。
}
}
...
注意! getLangOpts().C99中的if。診斷代碼將永遠不會執行高于c90的標準。
那么你肯定可以嘗試一下,自己建立clang并洗掉if中的那部分內容,從而最終得到if (!getLangOpts().CPlusPlus)。
我試了一下,它對我來說是有效的。
你可以用cmake -G "Ninja" -DCMAKE_BUILD_TYPE="Release" -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_TARGETS_TO_BUILD="X86" -DCMAKE_C_COMPILER="/usr/bin/gcc" -DCMAKE_CXX_COMPILER="/usr/bin/g " -DLLVM_PARALLEL_LINK_JOBS=2 -DLLVM_OPTIMIZED_TABLEGEN=ON path/to/llvm-project/llvm
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/334266.html
標籤:
上一篇:如何在不使用strtok()的情況下對字串進行標記?
下一篇:Ajax不能在標簽中顯示資料
