代码之家  ›  专栏  ›  技术社区  ›  Jeremy Friesner

如何在不复制代码的情况下创建不可转换的C类型?

  •  1
  • Jeremy Friesner  · 技术社区  · 8 年前

    我有一些带有各种函数的C代码,每个函数都将不同类型的“handle”对象作为参数。所有这些句柄的实现都是相同的(它只是一个带有空指针和项计数的结构),因此只声明一个实现似乎是合乎逻辑的——但我还希望C编译器在用户将错误类型的句柄传递给F时生成编译时错误。功能。

    我目前的方法使用 typedef 创建各种句柄类型,这些类型工作于文档,文档中的句柄类型是函数应该接受的,但编译器会自动转换,因此不会将类型不匹配标记为错误。有没有一个建议的方法来实现这个,不需要为每种类型手动复制句柄结构声明?

    玩具示例代码如下:

    typedef struct _FruitHandle {
       int _numItems;
       void * _items;
    } FruitHandle;
    
    typedef FruitHandle AppleHandle;
    typedef FruitHandle BananaHandle;
    // imagine a number of other fruits as well
    
    void EatAnApple(AppleHandle a) {}
    void EatABanana(BananaHandle b) {}
    // and so on -- each function should ONLY except its own fruit-handle-type as an argument!
    
    int main(int argc, char ** argv)
    {
       AppleHandle apple;
       BananaHandle banana;
    
       EatAnApple(apple);  // ok -- types match
       EatABanana(banana); // ok -- types match
    
       EatAnApple(banana); // type mismatch -- I want this to be a compile-time error, but it isn't!
       EatABanana(apple);  // type mismatch -- I want this to be a compile-time error, but it isn't!
    
       return 0;
    }
    
    2 回复  |  直到 8 年前
        1
  •  4
  •   Ben Jones Tim Goetz    8 年前

    this question

    typedef struct {
        int _numItems;
        void *_items;
    } FruitHandle;
    
    typedef struct {
        FruitHandle fruit_handle;
    } AppleHandle;
    
    typedef struct {
        FruitHandle fruit_handle;
    } BananaHandle;
    
    ...
    
        2
  •  2
  •   dbush    8 年前

    #define FRUIT(name) typedef struct _##name {\
       int _numItems;\
       void * _items;\
    } name
    
    FRUIT(AppleHandle);
    FRUIT(BananaHandle);
    

    typedef struct _AppleHandle { int _numItems; void * _items;} AppleHandle;
    typedef struct _BananaHandle { int _numItems; void * _items;} BananaHandle;