Forward declare a struct in Objective-C

前端 未结 3 2022
猫巷女王i
猫巷女王i 2021-01-01 21:57

I\'m creating a protocol, and one of the parameters to a method I\'m defining is a CMTime*. I would like to forward declare CMTime as opposed to in

相关标签:
3条回答
  • 2021-01-01 22:42

    A source compiled as ObjC has the same rules as C in this regard.

    A source compiled as ObjC++ has the same rules as C++ in this regard.

    @class MONClass; is a forward declaration of an ObjC type. Do not use it for structs.

    struct t_mon_struct; is a forward declaration of a named C or C++ struct. Do not use it for ObjC types. Technically, the compiler allows you to also forward declare a C++ class as a struct (provided of course the class is also declared in the global namespace).

    Thus, the root of the semantics all boil down to C (assuming this is an ObjC translation). I'll stop mentioning ObjC and C++ now.

    There are some common sources of complexity here:

    • the struct namespace
    • the struct's declaration
    • avoiding multiple definitions of labels

    struct t_mon_struct; is a forward declaration of a tagged struct. Specifically, that is whose name exists in the struct namespace.

    a tagged struct which exists in the struct namespace:

    struct t_mon_struct { int a; };
    

    an anonymous struct with a typedef in the global namespace:

    typedef struct { int a; } t_mon_struct;
    

    a tagged struct with a typedef in the global namespace:

    typedef struct t_mon_struct { int a; } t_mon_struct;
    

    CMTime is declared as follows:

    typedef struct
    {
        CMTimeValue    value;
        CMTimeScale    timescale;
        CMTimeFlags    flags;
        CMTimeEpoch    epoch;
    } CMTime;
    

    Specifically, the global typedef label CMTime is bound to an anonymous struct in the struct namespace, and may not be referenced unless its declaration is visible.

    Had CMTime been declared:

    typedef struct CMTime
    {
        CMTimeValue    value;
        CMTimeScale    timescale;
        CMTimeFlags    flags;
        CMTimeEpoch    epoch;
    } CMTime;
    

    then you could have gotten by using a forward declaration struct CMTime:

    struct CMTime;
    void foo(struct CMTime*);
    

    Since it wasn't declared that way, you'll need to #include its declaration, or devise a workaround.

    The complications worsen when the the struct's typedef is distinct from its tag. You can't bind to or redeclare a typedef (in C). However, you can sneak around it by using the name in the struct namespace -- which some library authors consider as being private.

    0 讨论(0)
  • 2021-01-01 22:44

    Just adding typedef before the struct does the trick for me.

    typedef struct CMTime;
    
    0 讨论(0)
  • 2021-01-01 22:49

    If you want the files which have the forward declaration to know about the contents of the struct, they need to either import a header (it can be in multiple places) where it is defined. You can forward declare a struct if you do not need to access its properties, but that is the extent of it.

    0 讨论(0)
提交回复
热议问题