c++ - 在没有 typedef 的情况下使用时显示编译错误的函数的 volatile 指针;需要帮助 w/"void (* volatile userFunc)(void)"

标签 c++ pointers function-pointers volatile pointer-to-member

我正在使用 C++ 类编写 Arduino 库。在类内部,我有一个私有(private)成员变量,它是一个指向函数的指针。

问题是我需要指针是可变的,因为指向函数的指针将被设置为外部一个ISR,并且可以在程序执行期间更改,但是函数将被调用 ISR 中。因此,我认为我需要一个指向非 volatile 函数的 volatile 指针,对吗?

无论如何,我正在做的是创建一种允许自定义用户函数的机制,该函数将由我的库定期调用。

基础知识:

这只是展示了您可以看到的基本部分。

.h文件

class myLib
{
  public:
  void attachOverflowInterrupt(void (*myFunc)());

  private:
  volatile void (*userOverflowFunction)(void);
}  

.cpp文件

void myLib::attachOverflowInterrupt(void (*myFunc)())
{
  //ensure atomic access
  uint8_t SREGbak = SREG; //back up interrupt state
  noInterrupts(); //interrupts off

  userOverflowFunction = myFunc; //attach function //<--the part that matters to my problem here

  SREG = SREGbak; //restore interrupt state 
}

//inside the interrupt, their function is called essentially like this:
this->userOverflowFunction();

Arduino .ino 文件(只显示必要部分)

void doSomething()
{
}

myLib1.attachOverflowInterrupt(doSomething);

此代码无法编译。我收到此错误:

error: invalid conversion from 'void (*)()' to 'volatile void (*)()' [-fpermissive] userOverflowFunction = myFunc; //attach function

但是,如果我在类里面这样做,它会编译:

class myLib
{
  public:
  void attachOverflowInterrupt(void (*myFunc)());
  //volatile void (*userOverflowFunction)(void); //compile error
  void (* volatile userOverflowFunction)(void); //<---compiles
} 

或者,如果我改为这样做,它会编译:

typedef void (*voidFuncPtr)(void);

class myLib
{
  public:
  void attachOverflowInterrupt(void (*myFunc)());
  //volatile void (*userOverflowFunction)(void); //compile error
  //void (* volatile userOverflowFunction)(void); //compiles
  volatile voidFuncPtr userOverflowFunction; //<---compiles
} 

那么,导致第一个失败但后两个编译的这三件事之间有什么区别?

volatile void (*userOverflowFunction)(void); //compile error
void (* volatile userOverflowFunction)(void); //compiles
volatile voidFuncPtr userOverflowFunction; //compiles

我做过的背景阅读:

  1. http://www.barrgroup.com/Embedded-Systems/How-To/C-Volatile-Keyword
  2. Why is a point-to-volatile pointer, like "volatile int * p", useful?

附加问题:

上面的第一个背景链接指出:
“指向非 volatile 数据的 volatile 指针非常少见(我想我已经用过一次),但我最好继续为您提供语法:”

int * volatile p;

那么,您什么时候会使用上述技术?就我而言?

最佳答案

问题

声明volatile void (*userOverflowFunction)(void);说你有一个指向返回类型 volatile void 的函数的指针.

虽然 volatile void相当概念化(更容易理解 volatile int 是什么),它仍然是一个有效的返回类型,并且它与 doSomething() 的返回类型不匹配.

解决方案

你说你希望指针是可变的。

用 C++ 翻译它给出:void (* volatile userOverflowFunction)(void);这是你的第一个发现。

您描述的第二个发现对应于定义函数指针类型,然后说它是该类型的 volatile 指针。两者是等价的。

编辑:补充说明

您使用的方法完全合乎逻辑:您的函数不是易变的(正如 Kerrek 已经在评论中指出的那样),但是您的中断处理程序需要获取可能以易变方式更改的指针的值。

您可能也有兴趣阅读有关 std::signal 的内容.因为你的函数指针不是 volatile std::sig_atomic_t ,您应该考虑使用第二种方法使其成为原子:std::atomic<voidFuncPtr> userOverflowFunction;

关于c++ - 在没有 typedef 的情况下使用时显示编译错误的函数的 volatile 指针;需要帮助 w/"void (* volatile userFunc)(void)",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31898819/

相关文章:

c++ - 是什么导致此代码中的段错误?

c - 将指针交换为 C 中的指针

c - C 中函数指针作为参数

c++ - 使用 TCL 编写嵌入式 SQLite 脚本

c++ - 使用模板时 C++ "const"神秘重载函数调用

c - 处理存储在指向 C 中多个字符串的指针数组中的单个字符串的问题

c - C中的void函数指针返回值

c++ - 如何将两个单独的 c++ 文件合并到一个程序中?

c++ - 长时间运行的 std::async 会饿死其他 std::async 吗?

c - 无法向 "point to"传递 C 中的函数指针数组