【问题标题】:C: Declare volatile pointer to functionC: 声明指向函数的 volatile 指针
【发布时间】:2011-06-20 03:43:17
【问题描述】:

如何在 C 中声明一个指向函数的指针,以使指针本身是易失的。

static void volatile (* f_pointer)(void*);

static void (volatile * f_pointer)(void*);

static void (* volatile f_pointer)(void*);

我为什么要问这个?我在http://wiki.answers.com/Q/Volatile_example_code_sample_coding_of_volatile_pointer 阅读了有关易失性指针的信息。

volatile 指针和指向 volatile 的指针有时会出现问题:

现在,事实证明,指针指向 volatile 变量很常见。 这两个声明都声明了 foo 成为指向易失整数的指针:

volatile int * foo; 
int volatile * foo; 

指向非易失性变量的易失性指针非常少见(我想我用过一次), 但我最好继续给你语法:

int * volatile foo;

所以,我想获得一个指向函数的 volatile 指针,而不是指向“volatile”函数的指针。

谢谢

【问题讨论】:

  • 为什么需要一个指向函数的易失指针?谁来改变这个指针?你知道volatile真的是什么意思吗?
  • @James McNellis,是的,我想要。该指针由线程 0 更改并由线程 1..7 用于启动函数。之间有一个障碍,但我希望编译器在进入障碍之前将此指针刷新到线程 0 中的内存。另外我希望线程 1..7 重新读取这个指针(有一个循环 { barrier, pointer read, calling function } )。我使用的系统有很多可用的寄存器,所以编译器可能会缓存很多变量。我说的对吗?
  • 如果屏障写入正确,编译器不应在其上缓存值 - volatile 应该是不必要的。
  • @caf,很高兴见到你。代码a=1; pthread_barrier(); b=a; 怎么样? pthread_barrier 是不是写错了?编译器对这个函数的内部一无所知。编译器能否在这个函数调用周围缓存a 的值(从它的角度来看,它是通常的函数调用)?编译器可以缓存任何非易失性变量。
  • 在正确的 pthreads 实现中,pthread_barrier_wait() 必须充当编译器屏障(防止值在其中缓存)。实际上,不需要特定的编译器支持,因为pthread_barrier_wait()是一个外部函数,所以编译器必须假设它可以修改任何全局变量或任何地址已被占用的变量(也就是说,从编译器的角度来看,它是pthread_barrier_wait() 可能修改了a,而不是另一个线程)。

标签: c volatile


【解决方案1】:

将星号视为“障碍”。比星号更接近变量名的限定符(constvolatile)修改指针本身。距离变量名比星号更远的限定符修改指针将引用的内容。因此,在这种情况下,您将:

static void * volatile f_pointer(void *);

当然,除了你需要括号来定义一个指向函数的指针而不是声明一个返回指针的函数:

static void (*volatile f_pointer)(void *);

static 是一个存储类而不是一个限定符,因此 not 在这种情况下也是如此。您只能为变量本身指定存储类,而不是它指向的内容。没有“指向外部 int 的指针”或“指向静态 int 的指针”之类的东西,只有“指向 int 的指针”。如果您指定一个存储类(staticextern),它总是首先出现

其他threads 已经讨论过线程和volatile 之间的关系,所以我不会在这里重复,只是指出这可能不会有用。

【讨论】:

    【解决方案2】:

    cdecl 非常适合解决这类问题:

    $ cdecl
    Type `help' or `?' for help
    cdecl> declare f_pointer as static volatile pointer to function(pointer to void) returning void
    static void (* volatile f_pointer)(void *)
    cdecl>
    

    cdecl来源:http://cdecl.org/files/cdecl-blocks-2.5.tar.gz

    【讨论】:

    • @osgx,它包含在很多开发环境中。我似乎记得从源代码构建我的,但我不记得我从哪里得到它。您可以通过cdecl.org在线使用它。
    • 谢谢!你能说出一些包含 cdecl 的 IDE 吗? (我认为包含 cdecl 的 IDE 必须非常用户友好)
    • @osgx,对不起-我不知道有这样的事情。我只是将它用作命令行程序。
    【解决方案3】:
    static void (* volatile f_pointer)(void*);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多