[Xcb] names of nested structs of named bitcase/case are prone to nameclashes. Solution?

Christian Linhart chris at DemoRecorder.com
Tue Sep 2 06:12:28 PDT 2014


Hi all,

While working on XInput I noticed a problem with nested structs which are
generated by named bitcase or named case.

In XInput thare are at least two structs where it makes sense to name the
cases with "key", "button" and "valuator".

This generates the following C-Code:

============================================
/**
 * @brief xcb_input_input_info_info_t
 **/
typedef struct xcb_input_input_info_info_t {
    struct _key {
        xcb_input_key_code_t   min_keycode; /**<  */
        xcb_input_key_code_t   max_keycode; /**<  */
        uint16_t               num_keys; /**<  */
        uint8_t                pad0[2]; /**<  */
    } key;
    struct _button {
        uint16_t               num_buttons; /**<  */
    } button;
    struct _valuator {
        uint8_t                axes_len; /**<  */
        uint8_t                mode; /**<  */
        uint32_t               motion_size; /**<  */
        xcb_input_axis_info_t *axes; /**<  */
    } valuator;
} xcb_input_input_info_info_t;
============================================

and 

============================================
/**
 * @brief xcb_input_input_state_data_t
 **/
typedef struct xcb_input_input_state_data_t {
    struct _key {
        uint8_t  num_keys; /**<  */
        uint8_t  pad0; /**<  */
        uint8_t  keys[32]; /**<  */
    } key;
    struct _button {
        uint8_t  num_buttons; /**<  */
        uint8_t  pad1; /**<  */
        uint8_t  buttons[32]; /**<  */
    } button;
    struct _valuator {
        uint8_t  num_valuators; /**<  */
        uint8_t  mode; /**<  */
        int32_t *valuators; /**<  */
    } valuator;
} xcb_input_input_state_data_t;
============================================

The C-Compiler does not accept this because C does not have scoping for struct names:
============================================
xinput.h:1414:12: error: redefinition of 'struct _key'
     struct _key {
            ^
xinput.h:188:12: note: originally defined here
     struct _key {            ^
============================================


How should we solve this?

I see the following possible solutions:

1. Automatically prefixing the names of these structs with the name of the outer struct, i.e.:
    ============================================
    /**
     * @brief xcb_input_input_state_data_t
     **/
    typedef struct xcb_input_input_state_data_t {
        struct xcb_input_input_state_data_key_t {
                uint8_t  num_keys; /**<  */
            uint8_t  pad0; /**<  */
            uint8_t  keys[32]; /**<  */
        } key;
        struct xcb_input_input_state_data_button_t {
            uint8_t  num_buttons; /**<  */
            uint8_t  pad1; /**<  */
            uint8_t  buttons[32]; /**<  */
        } button;
        struct xcb_input_input_state_data_valuator_t {
            uint8_t  num_valuators; /**<  */
            uint8_t  mode; /**<  */
            int32_t *valuators; /**<  */
        } valuator;
    } xcb_input_input_state_data_t;
    ============================================

   Pro: is a clean solution

   Contra: changes the API

2. Not naming these structs

    ============================================
    /**
     * @brief xcb_input_input_state_data_t
     **/
    typedef struct xcb_input_input_state_data_t {
        struct {
                uint8_t  num_keys; /**<  */
            uint8_t  pad0; /**<  */
            uint8_t  keys[32]; /**<  */
        } key;
        struct {
            uint8_t  num_buttons; /**<  */
            uint8_t  pad1; /**<  */
            uint8_t  buttons[32]; /**<  */
        } button;
        struct {
            uint8_t  num_valuators; /**<  */
            uint8_t  mode; /**<  */
            int32_t *valuators; /**<  */
        } valuator;
    } xcb_input_input_state_data_t;
    ============================================

   Pro: is also a clean solution

   Contra: 
	* changes the API
	* struct types cannot be accessed by application-code.

3. Workarounds in the xml, i.e. making sure that the case and bitcase-names 
   are globally unique accross all xml-files.

   Pro: does not change the existing API

   Contra:
	* uqly

	* name-clashes between different header-files are not detected by
	  the build of libxcb. But they may happen when building an application
	  that includes two headerfiles that cause a name-clash.
 	  (However, we could add a dummy compile-step which includes all
	  header-files in the same C-file.).

What do you think?

Chris




More information about the Xcb mailing list