簡體   English   中英

C 中的常量結構成員是如何處理的?

[英]How are constant struct members handled in C?

做這樣的事情可以嗎?

struct MyStruct {
    int x;
    const char y; // notice the const
    unsigned short z;
};
struct MyStruct AStruct;
fread(&MyStruct, sizeof (MyStruct), 1,
      SomeFileThatWasDefinedEarlierButIsntIncludedInThisCodeSnippet);

我通過從文件寫入整個結構來更改常量結構成員。 這應該怎么處理? 如果一個或多個結構成員是常量,這是寫入非常量結構的未定義行為嗎? 如果是這樣,處理常量結構成員的公認做法是什么?

這是未定義的行為。

C11 草案 n1570 說:

6.7.3 類型限定符

...

...

如果嘗試通過使用具有非 const 限定類型的左值來修改使用 const 限定類型定義的 object,則行為未定義。

我對此的解釋是:為了符合標准,您只能在 object 創建(又名初始化)期間設置 const 成員的值,例如:

struct MyStruct AStruct = {1, 'a', 2};  // Fine

正在做

AStruct.y = 'b';   // Error

應該給出一個編譯器錯誤。

您可以使用以下代碼欺騙編譯器:

memcpy(&AStruct, &AnotherStruct, sizeof AStruct);

它可能在大多數系統上都能正常工作,但根據 C11 標准,它仍然是未定義的行為。

另請參閱帶有指向 const 數據的目標指針的 memcpy

C 中的常量結構成員是如何處理的?

閱讀 C11 標准n1570及其與const限定符相關的 §6.7.3。

如果是這樣,處理常量結構成員的公認做法是什么?

這取決於您是否更關心嚴格遵守 C 標准,還是關心實際實現。 請參閱討論這些問題的這份報告草案(2020 年 6 月正在進行的工作)。 這些考慮取決於分配給您的項目的開發工作,以及您的軟件的可移植性(到其他平台)。

您可能不會在Covid 呼吸器的嵌入式軟件(或某些ICBM內部)和 web 服務器(如lighttpd或諸如libonion 之類的庫或某些FastCGI應用程序)上花費相同的精力在廉價的消費電器中或在一些廉價租用的 Linux VPS上運行。

還可以考慮在代碼上使用 static 分析工具,例如Frama-CClang static 分析器

關於未定義的行為,請務必閱讀此博客

參閱相關問題的答案。

我通過從文件寫入整個結構來更改常量結構成員。

那么字節順序問題和文件系統問題很重要。 Consider perhaps using libraries related to JSON , to YAML , perhaps mixed to sqlite or PostGreSQL or TokyoCabinet (and the source code of all these open source libraries, or from the Linux kernel , could be inspirational).

該標准對“對象”一詞的定義和使用有些草率。 對於像“所有 X 必須是 Y”或“沒有 X 可能是 Z”這樣的陳述是有意義的,X 的定義必須具有不僅滿足所有 X 的條件,而且明確排除所有不滿足的對象要求為 Y 或允許為 Z。

然而,“對象”的定義只是“執行環境中的數據存儲區域,其內容可以表示值”。 然而,這樣的定義未能明確是否每個可能的連續地址范圍總是一個“對象”,或者各種可能的地址范圍何時受制於適用於“對象”的約束以及何時不是。

為了使標准明確地將極端案例分類為已定義或未定義,委員會必須就是否應定義或未定義達成共識。 如果委員會成員根本不同意某些案件是否應定義或未定義,則以協商一致方式通過規則的唯一方法是,如果規則以一種模棱兩可的方式編寫,允許人們對每個人認為應該定義什么有矛盾的看法該規則支持他們的觀點。 雖然我不認為委員會成員明確想讓他們的規則模棱兩可,但我認為委員會不可能就沒有的規則達成共識。

鑒於這種情況,許多操作,包括更新具有恆定成員的結構,很可能屬於 realm 的操作,標准不要求實現有意義地處理,但標准的作者會期望實現會有意義地處理無論如何。

暫無
暫無

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

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