Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How and where to include stdint.h type definitions in a header file?

Tags:

c

header

If I want all of my *.c files that have proto.h included to use int32_t instead of int is it correct to write this into a header file called proto.h:

#ifndef PROTO_H_INCLUDED
#define PROTO_H_INCLUDED
#ifndef STDINT_H_INCLUDED
#define STDINT_H_INCLUDED
typedef int int32_t;
typedef unsigned int uint32_t;
typedef size_t uint32_t;
#endif

and then include proto.h into all the *.c files that need this typedef?

Or should I include stdint.h into all of my *.c files?

like image 972
polslinux Avatar asked Jul 05 '12 15:07

polslinux


1 Answers

This is correct, but not the best solution for a number of reasons.

  1. It requires extra work to curate this list of typedefs. They're already in stdint.h.
  2. Your typedefs aren't correct on some architectures, and you don't have any checks for that. If someone sees uint32_t, they expect it to be a 32-bit unsigned int on any architecture; this would be a nasty bug to track down.
  3. It's not clear to the users of your proto.h file that it includes stdint.h. Some will say that you should include as few files as possible; in my opinion it's far more important to be clear. Removing the proto.h inclusion in users' C files should only require removal of the references to functions declared in it, not adding an inclusion of stdint.h. You should add it to the .c file for clarity, and they'll want to do the same.
  4. You've added extra include guards around your typedefs, these aren't necessary - stdint.h (and every other header you'll use) already contains include guards.

For these reasons, I would suggest that in any header file where you need definitions from another header (for example, to use macros or typedefs in function prototypes) you should structure your files as follows:

proto.h

#ifndef PROTO_H_INCLUDED
#define PROTO_H_INCLUDED

// Typedefs for prototypes
#include <stdint.h>

unit32_t proto(int32_t *value, size_t length);

#endif

proto.c

#include <stdint.h>
#include "proto.h"  // Forward declare functions in this file

unit32_t proto(uint32_t *value, size_t length)
{
    // Do something
}

main.c

#include <stdint.h>
#include "proto.h"

int main(int argc, char *argv[])
{
    uint32_t values[] = { 1, 2, 3 };
    uint32_t result;
    // Could do 'uint32_t result, values[] = { 1, 2, 3 };' (one line)
    // but this is better for clarity
    size_t len = sizeof(values) / sizeof(values[0]);

    proto(values, len);
}
like image 146
Kevin Vermeer Avatar answered Oct 12 '22 18:10

Kevin Vermeer