簡體   English   中英

Clang-Tidy:根據未初始化的非局部變量、C 指針引用,用非常量表達式初始化非局部變量

[英]Clang-Tidy: Initializing non-local variable with non-const expression depending on uninitialized non-local variable, C pointer reference

我們有一段非常簡單的代碼,它發出警告,但看起來應該沒問題,並且運行正常。 我們知道通常編譯單元之間的初始化順序可能存在問題,但在這種情況下,我們使用指針進行初始化,因此不了解順序如何導致問題,或者此代碼如何可能出現任何問題。 請注意,在實際代碼中,我們有更復雜的結構場景,但下面的代碼顯示了基本問題。

編輯:已刪除 const 限定符,因為它們不會影響警告

文件1.c

int foo=42;

文件2.c

#include <stdio.h>

extern int foo;
// Clang-Tidy: Initializing non-local variable with non-const expression depending on uninitialized non-local variable 'foo'
int *bar=&foo;

int main() {
  printf("%d\n", *bar); // prints '42'
}

警告不是來自gcc而是來自clang-tidy 要重現運行:

clang-tidy -checks=* file1.c file2.c

clang-tidy警告一些不是問題的東西: foo是否被初始化在這個只取其地址的初始化程序中沒有區別。

此外foo是一個全局變量,因此它要么在定義它的模塊中靜態初始化,要么沒有初始化程序並在運行時由加載程序初始化為 0。 如果程序被編譯為 C++, foo可能會在運行時初始化,在調用main之前,可能通過運行初始化代碼,但這同樣沒有區別,因為在int *bar = &foo;只使用了它的地址int *bar = &foo;

您應該禁用此警告,如Cameron Tacklind 所述

正如其他人所提到的, clang-tidy准確地告訴您出了什么問題。

在這種情況下,我認為關鍵是句子的第一部分:“初始化非局部變量......”。

如果在main()聲明(和定義) bar則特定警告將消失:

#include <stdio.h>

extern int foo;

int main() {
  int *bar=&foo; // Still warns about const issues

  printf("%d\n", *bar);
}

或者,您可以很容易地忽略這些特定行的特定規則:

#include <stdio.h>

extern int foo;

// NOLINTNEXTLINE(cppcoreguidelines-interfaces-global-init)
int *bar=&foo;

int main() {
  printf("%d\n", *bar);
}

在 Ubuntu 20.04 中,我創建了這樣的 file1.c 和 file2.c,使用 gcc 編譯它們並運行,但是我沒有像上面提到的那樣收到任何警告,它工作得很好。

另外,在邏輯上,我認為這不會造成任何問題。

在 C 中,關鍵字const表示常量變量,不能更改。 在你的情況下, foo是一個常量變量,它的地址也是常量; 您將其地址分配給另一個常量指針變量bar ,因此bar始終指向foo ,並且它們都是常量變量,這意味着任何時候*bar等於foo ,反之亦然。

順便說一句,也許您在發布問題時很着急,但我仍然建議您添加; const int *bar=&foo的末尾,它駐留在file2.c

暫無
暫無

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

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