【问题标题】:C use macro struct in function prototypesC 在函数原型中使用宏结构
【发布时间】:2021-02-14 14:54:48
【问题描述】:

我正在使用宏在 C 中模拟模板。我想实现这样的目标:

// Struct.h
#define define_struct(type) \
  typedef struct MyStruct { \
    type value;             \
  }

struct MyStruct;
typedef struct MyStruct MyStruct;

MyStruct *createMyStruct();
// Struct.c
#include "Struct.h"
#include <stdlib.h>

MyStruct *createMyStruct() {
  MyStruct *str = malloc(sizeof(MyStruct));
  return str;
}

然后使用它:

#include "Struct.h"

define_struct(int);

int main() {
  MyStruct *str = createMyStruct();
}

但这不起作用,因为struct MyStruct; 是一个不完整的类型,而malloc(MyStruct) 对编译器没有意义。是否有可能做到这一点而不会出错?

附:我明白,为什么这不起作用,我绝对确定我永远不需要定义这个结构的 2 个实例,而且我不能使用 C++,只能使用普通 C。

【问题讨论】:

  • 请不要为此使用宏。它使代码难以阅读和调试。我为那些将在几年后回到这段代码并试图理解它的人感到同情。只做长手。从长远来看,让生活更轻松。
  • 您必须在范围内正确调用defined_struct 来编译Struct.c。此外,您将只能在任何给定程序中使用一种类型。如果您想要在程序中使用多个这些类型,则必须为不同类型创建具有不同名称的函数,而您还没有尝试这样做。这通常涉及在宏中使用## 运算符进行令牌粘贴,并且您需要的宏不仅仅是您目前拥有的宏。它不会使您的代码可读;它不会使您的代码易于理解;这将使其难以维护。不要!
  • 简而言之,如果你想要 C++,就使用 C++。
  • c 中的宏仅由预处理器使用。例如,在struct.c中你没有在使用MyStruct之前使用defined_struct(xxx),所以编译器无法编译未定义的结构。
  • 要了解为什么你得到了诊断,在编译“Struct.c”时让自己扮演编译器的角色:应该有多少字节在不知道MyStruct 有多大的情况下传递给malloc()

标签: c struct macros


【解决方案1】:

有一本名为C 接口和实现:创建可重用软件的技术 的经典书籍,其中对同一件事进行了深入的讨论。如果我记得的话,在第一章。

应该有2个解决方案:

  1. 也将createMyStruct 等所有成员函数定义为带有(type) 的宏。
  2. 使用impl 指针,例如:
struct MyStruct {
    void *impl;

    /* stuff that store actual type of imple and something else */
    some_type_to_store_type actual_type;
};

MyStruct *createMyStruct(some_type_to_store_type actual_type) {
  MyStruct *str = malloc(sizeof(Mystruct));
       // wow! sizeof Mystruct is fixed now
  str->impl = make_impl(actual_type);
  return str;
}

另外,有一些库使用这种编码风格,但我不记得名字了。尝试在谷歌搜索C OOP,应该有一些材料,例如这个看起来不错:https://www.state-machine.com/doc/AN_OOP_in_C.pdf.

【讨论】:

    猜你喜欢
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多