Menu

Problem referencing members in C structures

2014-07-08
2014-07-10
  • Martin Burnicki

    Martin Burnicki - 2014-07-08

    Hi folks,

    I'm actually putting lots of doxygen comments to some standard C header files describing some API structures, and stumbled across some warning or limitations when cross referencing structure members.

    Here is a piece of code I've put together to show what I mean:

    /**
     * @brief Signal types
     *
     * Used with ::MBG_SIGNAL_FRAME_CFG::type
     */
    enum MBG_SIGNAL_TYPES
    {
      MBG_SIGNAL_TYPE_E1,
      MBG_SIGNAL_TYPE_T1,
      N_MBG_SIGNAL_TYPES
    };
    
    /**
     * @brief Signal shapes
     *
     * Used with ::MBG_SIGNAL_FRAME_CFG::quality::e1::shape <-----------------
     */
    enum MBG_SIGNAL_SHAPES
    {
      MBG_SIGNAL_SHAPE_SINE,
      MBG_SIGNAL_SHAPE_RECT,
      N_MBG_SIGNAL_SHAPES
    };
    
    /**
     * @brief Configuration of a signal frame
     */
    typedef struct
    {
      uint32_t type;          ///< signal types, see ::MBG_SIGNAL_TYPES  <======
    
      union
      {
        struct
        {
          uint8_t  shape;       ///< see ::MBG_SIGNAL_SHAPES  <-----------------
          uint8_t  reserved_0;  ///< reserved, currently always 0
          uint16_t reserved_1;  ///< reserved, currently always 0
        } e1;                   ///< if ::type == ::MBG_SIGNAL_TYPE_E1  <======
    
        struct
        {
          uint16_t pulse_widh;  ///< pulse width
          uint16_t reserved_0;  ///< reserved, currently always 0
        } t1;                   ///< if ::type == ::MBG_SIGNAL_TYPE_E1  <======
    
      } quality;
    
    } MBG_SIGNAL_FRAME_CFG;
    

    This yields the following warnings:

    warning: explicit link request to 'type' could not be resolved
    

    This happens if I try to refer to a member field inside a structure from within a comment inside the same structure, i.e.

    ///< if ::type == ::MBG_SIGNAL_TYPE_E1
    

    If I use the full qualified "path" to the structure member it works OK. For example

    ///< if ::MBG_SIGNAL_FRAME_CFG::type == ::MBG_SIGNAL_TYPE_E1
    

    doesn't yield a warning, but makes the comments in the source code harder to read, IMO. Is there a valid short form?

    When I try to refer to first level structure members like ::MBG_SIGNAL_FRAME_CFG::type then everything is fine. However, a link request like

    ///< ::MBG_SIGNAL_FRAME_CFG::quality::e1::shape
    

    yields a warning saying:

    warning: explicit link request to 'MBG_SIGNAL_FRAME_CFG::quality::e1::shape' could not be resolved
    

    Of course I could defined the structures/unions not cascaded, but this would make the docs harder to read since you need to refer to the lowest level structer, then look up to the union where the structure is used, and finally look up the structure where the union is used.

    Is there any way to get this working?

    Thanks,
    Martin

     
    • Luis Vega

      Luis Vega - 2014-07-08

      I think that the error is probably caused by the style of your comment. Try removing the :: from the front of the referred item within the documentation.

      Also, suggest using:
      @see MBG_SIGNAL_TYPES
      @see MBG_SIGNAL_FRAME_CFG::type

      If you prefer "Used By" for some cases, you can create the costume tag @usedby (or similar) by adding the following to the ALIASES option in the Doxyfile:
      ALIASES = "usedby=\par Used By:\n"

      The final usage would look like this:
      @usedby MBG_SIGNAL_FRAME_CFG::type

      Also, don't forget to set the option OPTIMIZE_OUTPUT_FOR_C to YES in the Doxyfile.

      From: Martin Burnicki [mailto:mburnicki@users.sf.net]
      Sent: Tuesday, July 08, 2014 10:15 AM
      To: [doxygen:discussion]
      Subject: EXTERNAL: [doxygen:discussion] Problem referencing members in C structures

      Hi folks,

      I'm actually putting lots of doxygen comments to some standard C header files describing some API structures, and stumbled across some warning or limitations when cross referencing structure members.

      Here is a piece of code I've put together to show what I mean:

      /**

      • @brief Signal types

      *

      • Used with ::MBG_SIGNAL_FRAME_CFG::type

      */

      enum MBG_SIGNAL_TYPES

      {

      MBG_SIGNAL_TYPE_E1,

      MBG_SIGNAL_TYPE_T1,

      N_MBG_SIGNAL_TYPES

      };

      /**

      • @brief Signal shapes

      *

      • Used with ::MBG_SIGNAL_FRAME_CFG::quality::e1::shape <-----------------

      */

      enum MBG_SIGNAL_SHAPES

      {

      MBG_SIGNAL_SHAPE_SINE,

      MBG_SIGNAL_SHAPE_RECT,

      N_MBG_SIGNAL_SHAPES

      };

      /**

      • @brief Configuration of a signal frame

      */

      typedef struct

      {

      uint32_t type; ///< signal types, see ::MBG_SIGNAL_TYPES <======

      union

      {

      struct
      
      {
      
        uint8_t  shape;       ///< see ::MBG_SIGNAL_SHAPES  <-----------------
      
        uint8_t  reserved_0;  ///< reserved, currently always 0
      
        uint16_t reserved_1;  ///< reserved, currently always 0
      
      } e1;                   ///< if ::type == ::MBG_SIGNAL_TYPE_E1  <======
      
      struct
      
      {
      
        uint16_t pulse_widh;  ///< pulse width
      
        uint16_t reserved_0;  ///< reserved, currently always 0
      
      } t1;                   ///< if ::type == ::MBG_SIGNAL_TYPE_E1  <======
      

      } quality;

      } MBG_SIGNAL_FRAME_CFG;

      This yields the following warnings:

      warning: explicit link request to 'type' could not be resolved

      This happens if I try to refer to a member field inside a structure from within a comment inside the same structure, i.e.

      ///< if ::type == ::MBG_SIGNAL_TYPE_E1

      If I use the full qualified "path" to the structure member it works OK. For example

      ///< if ::MBG_SIGNAL_FRAME_CFG::type == ::MBG_SIGNAL_TYPE_E1

      doesn't yield a warning, but makes the comments in the source code harder to read, IMO. Is there a valid short form?

      When I try to refer to first level structure members like ::MBG_SIGNAL_FRAME_CFG::type then everything is fine. However, a link request like

      ///< ::MBG_SIGNAL_FRAME_CFG::quality::e1::shape

      yields a warning saying:

      warning: explicit link request to 'MBG_SIGNAL_FRAME_CFG::quality::e1::shape' could not be resolved

      Of course I could defined the structures/unions not cascaded, but this would make the docs harder to read since you need to refer to the lowest level structer, then look up to the union where the structure is used, and finally look up the structure where the union is used.

      Is there any way to get this working?

      Thanks,
      Martin


      Problem referencing members in C structureshttps://sourceforge.net/p/doxygen/discussion/130994/thread/515ae0aa/?limit=50#cf94


      Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/doxygen/discussion/130994/https://sourceforge.net/p/doxygen/discussion/130994

      To unsubscribe from further messages, please visit https://sourceforge.net/auth/subscriptions/https://sourceforge.net/auth/subscriptions

       
      • Martin Burnicki

        Martin Burnicki - 2014-07-09

        Luis,

        thanks for your ideas. The approach with using an alias sounds interesting since it makes the source code more readable.

        However, just omitting the leading '::' in the references is not what I want, and it doesn't really help. If I've understood correctly how doxygen works, and from what I've seen in the doxygen output, then as long as the spelling in the comment is correct everything is fine, and as far as I can see there's no difference in the result:

        @see ::MBG_SIGNAL_FRAME_CFG::type  // works correctly, creates a reference link
        @see MBG_SIGNAL_FRAME_CFG::type    // works correctly, creates a reference link
        

        However, if there's a typo in the referenced symbol name (e.g. 'typex' instead of 'type'):

        @see ::MBG_SIGNAL_FRAME_CFG::typex  // creates no reference, but emits a warning due to the typo
        @see MBG_SIGNAL_FRAME_CFG::typex    // creates no reference, and does't even emit a warning
        

        So if I use the explicite link request '::' prepending the names of the referenced symbols then doxygen provides me with a warning if the referenced symbol can't be found. This is very much appreciated since it helps checking the consistency of the generated docs, similar as the C compiler gives a warning if a function is called with parameters which don't match the function prototype.

        So if I simply omit the leading '::' then of course no warning is generated if doxygen doesn't find the symbol I'd like to reference, but also no reference link is created to the target data field is generated.

        So the reason of the problem is not the leading '::' but the syntax required to specify a member field in a cascaded structure:

        typedef struct
        {
          int type;
        
          union
          {
            struct
            {
              int shape;
              ...
            } e1;
            ...
          } quality;
        
        } MBG_SIGNAL_FRAME_CFG;
        

        When refering to the fields of this cascaded structure:

        @see ::MBG_SIGNAL_FRAME_CFG::type                 // works correctly, creates a reference link
        @see ::MBG_SIGNAL_FRAME_CFG::quality::e1::shape   // doesn't work, yields warning
        

        As far as I understand the problem is not due to the leading '::' but due to way I try to specify a member at the lower level of the cascaded structure. The question is if I need a different way to specify the data field 'shape', or if doxygen doesn't support a direct reference to a data field in a cascaded structure.

        BTW, this is with doxygen 1.8.6/1.8.7 under Windows, and yes, OPTIMIZE_OUTPUT_FOR_C has already been set to YES in the doxyfile.

        Any ideas are appreciated.

        Martin

         
  • Martin Burnicki

    Martin Burnicki - 2014-07-10

    OK, found a solution. Just for the records: if I give local names to the embedded structures, i.e.:

    typedef struct
    {
      int type;
    
      union quality
      {
        struct e1
        {
          int shape;
          ...
        } e1;
        ...
      } quality;
    
    } MBG_SIGNAL_FRAME_CFG;
    

    then both references

    @see ::MBG_SIGNAL_FRAME_CFG::type
    @see ::MBG_SIGNAL_FRAME_CFG::quality::e1::shape
    

    work fine, create reference links, and yield a substantiated warning if the names are not spelled properly.

    Martin

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.