簡體   English   中英

聲明為 const,但定義為非常量,C

[英]Declaring as const, but defining as non-const, C

在我的標題中聲明一個 const 變量是否有效,但將其定義為非常量變量以供內部使用?

在 header 文件中聲明變量的唯一合乎邏輯的方法是將它們聲明為extern

由於#include僅將 header 文件的文本插入到源代碼文件( https://godbolt.org/z/nor8nz )中,您可以在單個源文件中簡單地測試您的想法:

extern const int x;

int x;

https://godbolt.org/z/PWEzGM

你會得到錯誤:

1
ARM gcc 8.2
- 347ms

<source>:4:5: error: conflicting type qualifiers for 'x'
 int x;
     ^
<source>:2:18: note: previous declaration of 'x' was here
 extern const int x;
                  ^
Compiler returned: 1

不,這會導致未定義的行為。

C17 6.6.7 (2):

所有引用相同 object 或 function 的聲明應具有兼容類型; 否則,行為未定義。

6.7.3 (11):

對於要兼容的兩個限定類型,兩者都應具有兼容類型的相同限定版本; 說明符或限定符列表中類型限定符的順序不影響指定的類型。

由於const是限定符,因此intconst int等類型不兼容,因此具有相同 object 的intconst int聲明是未定義的行為。 (並且 object 的定義本身就是一個聲明,所以它很重要。)

在實踐中,許多可能的不良后果之一可能是在具有const聲明的源文件(翻譯單元)中,編譯器可能會假定該變量實際上是常量,並且可能無法注意到它是否被修改。 例如,如下代碼:

#include <stdio.h>
extern const int x;
void bar(void);
void foo(void) {
    printf("%d\n", x);
    bar();
    printf("%d\n", x);
}

可以在調用bar()時將x的值緩存在被調用者保存的寄存器中,因此總是會打印兩次相同的值。 參見神螺栓 即使另一個文件包含

int x = 5;
void bar(void) {
    x = 6;
}

我希望有更好的答案可以解決有關有效性的直接問題。

但這幾乎可以肯定是一種不好的方法。 我的建議是使用 function 來代替返回值。 另一種選擇是使用指向 const 的指針。 就像是:

int x;
int *const ptr = &x;

以您描述的方式使用全局變量是危險的領域。 如果我想做那樣的事情,我可能會接受我必須非常小心。

有人可能會想使用這樣的指針:

const int x;
int *ptr = &x; // Bad, bad idea

但不要嘗試這樣做,因為它會調用未定義的行為。 資料來源:我們可以通過指針更改用 const 定義的 object 的值嗎?

暫無
暫無

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

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