我正在閱讀一本關于為微控制器撰寫現代 C 代碼的書,名為“實時 C ”。我正在嘗試自己撰寫書中的代碼。但是,在從書中復制代碼并嘗試構建它時,出現了以下編譯錯誤:
錯誤 C2131:運算式未計算為常量。
訊息:遇到非常量(子)運算式
我在下面插入了代碼的相關部分:
#include <cstdint>
#include <iomanip>
#include <iostream>
namespace mcal
{
namespace reg
{
// Simulate the transmit and receive hardware buffers on the PC.
std::uint8_t dummy_register_tbuf;
std::uint8_t dummy_register_rbuf;
}
}
class communication
{
private:
static constexpr std::uint8_t* tbuf = reinterpret_cast<std::uint8_t*>(&mcal::reg::dummy_register_tbuf);
static constexpr std::uint8_t* rbuf = reinterpret_cast<std::uint8_t*>(&mcal::reg::dummy_register_rbuf);
};
/* rest of the nonrelated code */
錯誤指示發生轉換的那兩行。我知道我們嘗試使用靜態 constexpr 整數類成員變數,因為這可以確保對它們進行優化(常量折疊)。我認為錯誤的發生是因為我們試圖將一個非常量變數設定為一個常量變數,但我肯定是錯的。因此,我懇請您向我解釋這里的真正問題是什么以及作者為什么會犯這樣的錯誤(如果是錯誤的話)。另外,如果您另外指出正確的鑄造方式,我將不勝感激。非常感謝你。
uj5u.com熱心網友回復:
目前尚不清楚背后的意圖是什么reinterpret_cast,但該程式格式不正確。
constexpr在變數上要求初始值設定項是一個常量運算式。但是,如果運算式會計算 a ,則運算式被取消為常量運算式的資格reinterpret_cast。因此初始化是格式錯誤的。
但是,初始化中的任何其他內容都不會阻止它成為常量運算式,因此
static constexpr std::uint8_t* tbuf = &mcal::reg::dummy_register_tbuf;
將正常作業并且reinterpret_cast無論如何都是多余的,因為它會在指定為產生相同值的相同指標型別之間進行轉換。
直到 v19.16 的 GCC、ICC 和 MSVC 似乎都錯誤地接受了代碼(https://godbolt.org/z/YKjhxqo3v)。也許作者只在這些編譯器之一上測驗了代碼。
對于GCC有一個bug報告在這里。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/402502.html
標籤:
