[En-Nut-Discussion] Initialising structs

Bernd Walter enut at cicely.de
Fri Feb 4 00:51:10 CET 2011


Currently I face initialisation of IFNET:

typedef struct ifnet IFNET;

struct ifnet {
    uint8_t if_type;        /*!< \brief Interface type.
                            *  Either IFT_ETHER or IFT_PPP.
                            */
    uint32_t if_flags;      /*!< \brief Interface flags. */
    uint8_t if_mac[6];      /*!< \brief Hardware net address. */
    uint32_t if_local_ip;   /*!< \brief IP address. */
    uint32_t if_remote_ip;  /*!< \brief Remote IP address for point to point. */
    uint32_t if_mask;       /*!< \brief IP network mask. */
    uint16_t if_mtu;        /*!< \brief Maximum size of a transmission unit. */
    uint16_t if_pkt_id;     /*!< \brief Packet identifier. */
    ARPENTRY *arpTable;     /*!< \brief Linked list of arp entries. */
    MCASTENTRY *if_mcast;   /*!< \brief Linked list of multicast address entries. */
    void (*if_recv) (NUTDEVICE *, NETBUF *);    /*!< \brief Receive routine. */
    int (*if_send) (NUTDEVICE *, NETBUF *);             /*!< \brief Send routine. */
    int (*if_output) (NUTDEVICE *, uint16_t, uint8_t *, NETBUF *);  /*!< \brief Media output routine. */
    int (*if_ioctl) (NUTDEVICE *, int, void *); /*!< \brief Interface specific control function. */
};

A typical initialisation within a driver looks like this:
static IFNET ifn_eth0 = {
    IFT_ETHER,                  /*!< \brief Interface type, if_type. */
    0,                          /*!< \brief Interface flags, if_flags. */
    {0, 0, 0, 0, 0, 0},         /*!< \brief Hardware net address, if_mac. */
    0,                          /*!< \brief IP address, if_local_ip. */
    0,                          /*!< \brief Remote IP address for point to point, if_remote_ip. */
    0,                          /*!< \brief IP network mask, if_mask. */
    ETHERMTU,                   /*!< \brief Maximum size of a transmission unit, if_mtu. */
    0,                          /*!< \brief Packet identifier, if_pkt_id. */
    0,                          /*!< \brief Linked list of arp entries, arpTable. */
    0,                          /*!< \brief Linked list of multicast address entries, if_mcast. */
    NutEtherInput,              /*!< \brief Routine to pass received data to, if_recv(). */
    DmOutput,                   /*!< \brief Driver output routine, if_send(). */
    NutEtherOutput              /*!< \brief Media output routine, if_output(). */
};

Now about IPv6 and IPv4 Multicast this struct needs major changes,
including some fields under #ifdef to avoid unrequired memory use.
The problem is that with an initialisation list like the above the
compiler can't always catch programming errors within driver code.

With C99 it is also possible to initialise a struct in the following way:
static IFNET ifn_eth0 = {
    .if_type = IFT_ETHER,             /*!< \brief Interface type, if_type. */
    .if_flags = 0,                    /*!< \brief Interface flags, if_flags. */
    .if_mac = {0, 0, 0, 0, 0, 0},     /*!< \brief Hardware net address, if_mac. */
    .if_local_ip = 0,                 /*!< \brief IP address, if_local_ip. */
    .if_remote_ip = 0,                /*!< \brief Remote IP address for point to point, if_remote_ip. */
    .if_mask = 0,                     /*!< \brief IP network mask, if_mask. */
    .if_mtu = ETHERMTU,               /*!< \brief Maximum size of a transmission unit, if_mtu. */
    .if_pkt_id = 0,                   /*!< \brief Packet identifier, if_pkt_id. */
    .arpTable = 0,                    /*!< \brief Linked list of arp entries, arpTable. */
    .if_mcast = 0,                    /*!< \brief Linked list of multicast address entries, if_mcast. */
    .if_recv = NutEtherInput,         /*!< \brief Routine to pass received data to, if_recv(). */
    .if_send = DmOutput,              /*!< \brief Driver output routine, if_send(). */
    .if_output = NutEtherOutput,      /*!< \brief Media output routine, if_output(). */
};

And since this is a static struct, which already defaults to 0 it
can be shorten to just:
static IFNET ifn_eth0 = {
    .if_type = IFT_ETHER,             /*!< \brief Interface type, if_type. */
    .if_mtu = ETHERMTU,               /*!< \brief Maximum size of a transmission unit, if_mtu. */
    .if_recv = NutEtherInput,         /*!< \brief Routine to pass received data to, if_recv(). */
    .if_send = DmOutput,              /*!< \brief Driver output routine, if_send(). */
    .if_output = NutEtherOutput,      /*!< \brief Media output routine, if_output(). */
};

Do we need to care about compilers not supporting this style?

-- 
B.Walter <bernd at bwct.de> http://www.bwct.de
Modbus/TCP Ethernet I/O Baugruppen, ARM basierte FreeBSD Rechner uvm.



More information about the En-Nut-Discussion mailing list