从易失性结构中索引元素在 C++ 中不起作用

Fra*_*uss 18 c++

我有这个代码:

\n
typedef struct {\n    int test;\n} SensorData_t;\nvolatile SensorData_t sensorData[10];\n\nSensorData_t getNextSensorData(int i)\n{\n    SensorData_t data = sensorData[i];\n    return data;\n}\n\n\nint main(int argc, char** argv) {\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n

它可以使用 gcc 版本 8.3 进行编译,但不能使用 g++ 进行编译。错误信息:

\n
main.c: In function \xe2\x80\x98SensorData_t getNextSensorData(int)\xe2\x80\x99:\nmain.c:8:34: error: no matching function for call to \xe2\x80\x98SensorData_t(volatile SensorData_t&)\xe2\x80\x99\n  SensorData_t data = sensorData[i];\n                                  ^\nmain.c:3:3: note: candidate: \xe2\x80\x98constexpr SensorData_t::SensorData_t(const SensorData_t&)\xe2\x80\x99 <near match>\n } SensorData_t;\n   ^~~~~~~~~~~~\nmain.c:3:3: note:   conversion of argument 1 would be ill-formed:\nmain.c:8:34: error: binding reference of type \xe2\x80\x98const SensorData_t&\xe2\x80\x99 to \xe2\x80\x98volatile SensorData_t\xe2\x80\x99 discards qualifiers\n  SensorData_t data = sensorData[i];\n                      ~~~~~~~~~~~~^\nmain.c:3:3: note: candidate: \xe2\x80\x98constexpr SensorData_t::SensorData_t(SensorData_t&&)\xe2\x80\x99 <near match>\n } SensorData_t;\n   ^~~~~~~~~~~~\nmain.c:3:3: note:   conversion of argument 1 would be ill-formed:\nmain.c:8:34: error: cannot bind rvalue reference of type \xe2\x80\x98SensorData_t&&\xe2\x80\x99 to lvalue of type \xe2\x80\x98volatile SensorData_t\xe2\x80\x99\n  SensorData_t data = sensorData[i];\n
Run Code Online (Sandbox Code Playgroud)\n

我不确定是否需要为data变量和返回类型添加 volatile,因为它是复制的,所以不需要。但我也从中断访问sensorData数组(在嵌入式系统上),所以我认为我需要volatile顶级变量sensorData。

\n

str*_*ger 14

您的程序正在尝试复制一个SensorData_t对象。编译器提供具有以下签名的复制构造函数:

SensorData_t(const SensorData_t &)
Run Code Online (Sandbox Code Playgroud)

此复制构造函数无法使用volatile参数,因此会出现编译错误。

您可以编写自己的复制构造函数,该构造函数适用于volatile SensorData_t对象(以及非volatile SensorData_t对象):

struct SensorData_t {
    SensorData_t() = default;

    SensorData_t(const volatile SensorData_t &other)
        : test(other.test) {
    }

    int test;
};
Run Code Online (Sandbox Code Playgroud)


raw*_*rex 5

作为已接受答案的替代方案,如果这是全局的getNextSensorData简单getter函数,您可以考虑避免完全从数组中复制数据sensorData

// Intorduce type alias
using SD = const volatile SensorData_t&;

SD getNextSensorData(int i)
{
    return sensorData[i];
}
Run Code Online (Sandbox Code Playgroud)

这样(如果适合设计),您将使定义代码更加简洁。但我必须注意,其用法比复制情况稍微不那么直接:

int main() {
    // Type alias
    SD sd1 = getNextSensorData(0);
    // Deduced type
    auto&& sd2 = getNextSensorData(1);
    // Explicit type
    const volatile SensorData_t& sd3 = getNextSensorData(2);
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个坏主意,因为它将对易失性对象的实际访问从“get”抽象转移到代码后面的某个未知点。“易失性”强烈表明访问的时间或顺序至关重要。 (5认同)