【问题标题】:Strange pointer casting with void *使用 void * 进行奇怪的指针转换
【发布时间】:2014-08-13 12:25:16
【问题描述】:

我们正在共同开展有关嵌入式 Linux 与 C 和 C++ 的项目。 我最近在一个函数中遇到了一个奇怪的语句:

bool StrangeFunction(void* arg1, void* arg2, void* arg3)
{
    (void)arg1;
    (void)arg2;
    (void)arg3;

    unsigned long keycode = (unsigned long)arg2;

    switch(keycode)
    {
...

我在上面的代码中有两个问题

  1. (void)arg1; 是什么意思?
  2. 是否可以使用unsigned long keycode = (unsigned long)arg2;

如果您不介意,我需要一些解释和相关链接来解释这些主题。 谢谢。

【问题讨论】:

    标签: c casting void-pointers


    【解决方案1】:
    1. 它是为了消除关于未使用参数的编译器警告。

    2. 可以,但不可移植。如果在给定平台上的地址适合unsigned long,那很好。在可移植此代码的平台上使用uintptr_t。

    【讨论】:

    • 在 GCC 4.8.2 中,为什么第二行给出了关于 [-fpermissive] 的错误?因为据我所知,一种类型是指针,另一种不是指针。还是我错过了什么?
    • @FredrickGauss:根据 GCC 文档 (gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Option-Summary.html),-fpermissive 是 C++ 选项。我不知道C++。对不起。
    【解决方案2】:

    转换为void 很可能用于消除来自编译器的关于未使用变量的警告,请参阅Suppress unused-parameter compiler warnings in C/C++:

    如果可能,您应该使用uintptr_t 而不是unsigned long,这是一种能够保存指针的无符号整数类型。我们可以从草案 C99 标准部分 7.18.1.4 能够保存对象指针的整数类型 中看到:

    以下类型指定无符号整数类型,其 任何指向 void 的有效指针都可以转换为此类型的属性, 然后转换回指向void的指针,结果将比较 等于原来的指针:

    uintptr_t

    【讨论】:

      【解决方案3】:

      (void)arg1 什么都不做,只是让编译器使用这个变量。这是一种让函数接受未使用的参数但避免任何“参数未使用”编译器警告的方法。

      第二件事用于将无符号长整数传递给采用void * 的函数。无论如何,如果您正在处理 C++,那么拥有一个重载函数可能会更好。这也有一个缺点,即要求指针至少与unsigned long 一样大,因此它可能无法在某些平台上工作。

      【讨论】:

      • 也谢谢你。对于我的第二种情况,我们只对C 感兴趣,即使C++,我们根本无法使用另一个重载函数。
      猜你喜欢
      • 2013-06-12
      • 2021-01-29
      • 2021-04-08
      • 2021-09-23
      • 2021-05-07
      • 2014-12-17
      • 2015-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多