【问题标题】:Pointer to type within a macro, C在宏中键入的指针,C
【发布时间】:2015-06-01 03:52:17
【问题描述】:

我在尝试在宏中表达指向某个类型的指针时遇到了问题。

举这个简单的例子。

#define INDEX_OF_DATA(data, type, index) \
    ((type *)data)[index]

这行得通:

INDEX_OF_DATA(buffer, float, 3);

失败的地方:

INDEX_OF_DATA(buffer, float[2], 3);

因为演员表应该是(float(*)[2])

有没有办法表达type 的指针”,...而不使用typeof? (这不是标准 C)。


请注意,当然还有其他方法可以使这个特定示例工作。例如,转换为 char 并偏移 sizeof(type) * index。但我对用 C 语言表达pointer to type 的方式很感兴趣。

【问题讨论】:

  • 我不认为没有扩展这是可能的,但我很想知道是否有人有更好的主意。
  • c++ 在类型推断方面有更好的解决方案,但对于 C,你的选择几乎没有

标签: c c-preprocessor


【解决方案1】:

用 C 类型做非常复杂的事情可能是一项有趣的运动,但在实际代码中却非常令人困惑。

为了避免过于复杂的指针表达式,人们经常使用typedef

如果您typedef 您希望使用您的此宏的所有类型,则不会有任何问题。观察:

#include <stdlib.h>

#define INDEX_OF_DATA(data, type, index) \
    ((type *)data)[index]


int main(void) {
    float (*buffer)[2] = malloc(4 * sizeof(float[2]));

    typedef float t_f2arr[2];

    INDEX_OF_DATA(buffer, t_f2arr, 3)[0] = 1.1f;

    return 0;
}

这正是你想要的!

【讨论】:

  • >main.cpp: In function 'int main()': >main.cpp:17:32: error: 从 'void*' 到 'float (*)[2]' 的无效转换[-fpermissive] > float (*buffer)[2] = malloc(4 * sizeof(float[2]));
  • @Alper91 这是一个 C 问题,而不是 C++ 问题。在 C++ 中使用 malloc 没有类型转换是非法的(因为没有从 void* 到其他指针类型的隐式转换),所以在 C++ 中你需要做 (float (*)[2])malloc(...) 或向上移动 typedef 并做 (t_f2arr*)malloc(...)
【解决方案2】:

如果我们想保留原始宏,我们可以使用这个技巧:

#define INDEX_OF_DATA(data, type, index) ((type*)data)[index]

struct mystruct { float f[2]; };
mystruct* p = &INDEX_OF_DATA(buffer, mystruct, 3);

不幸的是,这个解决方案可能会受到结构填充的影响,所以最好检查一下:

static_assert(sizeof(mystruct) == sizeof(float (*)[2]), "padding found");

【讨论】:

  • 这甚至不会在 C 中编译
  • @texasbruce 是的,你是对的。即使我的解决方案并不完美,它也可能激发其他更好的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-08
  • 1970-01-01
  • 2015-07-18
相关资源
最近更新 更多