当前位置: 首页 > 知识库问答 >
问题:

在C语言中,索引来自易失性结构的元素不起作用

柯浩壤
2023-03-14

我有这个代码:

typedef struct {
    int test;
} SensorData_t;
volatile SensorData_t sensorData[10];

SensorData_t getNextSensorData(int i)
{
    SensorData_t data = sensorData[i];
    return data;
}


int main(int argc, char** argv) {

}

它使用gcc版本8.3编译,但不使用g。错误消息:

main.c: In function ‘SensorData_t getNextSensorData(int)’:
main.c:8:34: error: no matching function for call to ‘SensorData_t(volatile SensorData_t&)’
  SensorData_t data = sensorData[i];
                                  ^
main.c:3:3: note: candidate: ‘constexpr SensorData_t::SensorData_t(const SensorData_t&)’ <near match>
 } SensorData_t;
   ^~~~~~~~~~~~
main.c:3:3: note:   conversion of argument 1 would be ill-formed:
main.c:8:34: error: binding reference of type ‘const SensorData_t&’ to ‘volatile SensorData_t’ discards qualifiers
  SensorData_t data = sensorData[i];
                      ~~~~~~~~~~~~^
main.c:3:3: note: candidate: ‘constexpr SensorData_t::SensorData_t(SensorData_t&&)’ <near match>
 } SensorData_t;
   ^~~~~~~~~~~~
main.c:3:3: note:   conversion of argument 1 would be ill-formed:
main.c:8:34: error: cannot bind rvalue reference of type ‘SensorData_t&&’ to lvalue of type ‘volatile SensorData_t’
  SensorData_t data = sensorData[i];

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

共有2个答案

蓟安歌
2023-03-14

如果getNextSensorData是全局sensorData的一个简单getter函数,您可以考虑避免从阵列中完全复制数据,以替代公认的答案:

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

SD getNextSensorData(int i)
{
    return sensorData[i];
}

这样(如果它适合设计),您将使代码的定义更加简洁。但我必须指出,这种用法比复制的情况要不那么直接:

int main() {
    // Type alias
    SD sd1 = getNextSensorData(0);
    // Deduced type
    auto&& sd2 = getNextSensorData(1);
    // Explicit type
    const volatile SensorData_t& sd3 = getNextSensorData(2);
}
韦思淼
2023-03-14

您的程序正在尝试复制传感器数据\u t对象。编译器提供具有以下签名的副本构造函数:

SensorData_t(const SensorData_t &)

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

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

struct SensorData_t {
    SensorData_t() = default;

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

    int test;
};
 类似资料:
  • 所有的中断函数都能正常工作,但是过程函数却让我很生气。 我会感激任何我没注意的把戏。

  • 本文向大家介绍详解C语言中结构体的自引用和相互引用,包括了详解C语言中结构体的自引用和相互引用的使用技巧和注意事项,需要的朋友参考一下 结构体的自引用(self reference),就是在结构体内部,包含指向自身类型结构体的指针。 结构体的相互引用(mutual reference),就是说在多个结构体中,都包含指向其他结构体的指针。 1. 自引用 结构体 1.1 不使用typedef时 错误的

  • 主要内容:结构体变量,成员的获取和赋值前面的教程中我们讲解了 数组(Array),它是一组具有相同类型的数据的集合。但在实际的编程过程中,我们往往还需要一组类型不同的数据,例如对于学生信息登记表,姓名为字符串,学号为整数,年龄为整数,所在的学习小组为字符,成绩为小数,因为数据类型不同,显然不能用一个数组来存放。 在C语言中,可以使用 结构体(Struct)来存放一组不同类型的数据。结构体的定义形式为: struct 结构体名{    

  • 本文向大家介绍C语言数据结构之简易计算器,包括了C语言数据结构之简易计算器的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了C语言简易计算器的具体代码,供大家参考,具体内容如下 主要解决了处理负数、小数等的基础运算操作,无图形界面 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 计算机和人类发明的算盘一样,是一种计算工具。而计算机的发明就是要将人类从简单重复劳动中解放出来,所以计算机特别善于进行简单而需要大量人力才能完成的工作。 循环的做一件事情就是这样一种简单而需要耗费大量精力才能完成的一件事情。而且人工在处理这个事情的时候,还会经常出现各种错误。 循环作为计算机程序设计语言中基本的流控制语言,包含在几乎所有的程序中。比如我们常见的累加,计数,等等都是可以通过循环来完成

  • C 语言与大多数计算机语言一样是按照语句的顺序逐条执行的。如同流水一样,从上到下顺序执行。这就如同我们每天的日常生活,对于上班族来说,就是起床,洗漱,吃早饭,上班,午饭。下班,晚饭,睡觉。感觉一切都平淡无奇。但是如果你想去购买一台电脑怎么办?这不是一件每天都发生的流水事件,而且你需要在有足够的钱的情况下才能购买。这个时候,你就要在满足有钱的条件下打破原有的生活顺序,去卖场购买一台电脑。这就是生活中