Misha M
Misha M

Reputation: 11309

GCC strange behaviour with full path include vs search path include

I've encountered GCC include behavior that I'm trying to understand. The example I'm providing is the simplest test code, the actual code (and this behavior) are the result of a tool I'm using to instrument my code. I have to use this tool. I'm just trying to understand the reasons for getting the error. Interestingly enough, g++ works fine. Here's the example:

If I include <sys/types.h> everything compiles just fine, but if I include "/usr/include/sys/types.h" then I get an error.

Here's the error I get running the first gcc command below that includes the full path:

In file included from hello.c:7:
/usr/include/sys/types.h:195: error: redefinition of typedef ‘int8_t’
hello.c:5: error: previous declaration of ‘int8_t’ was here

Compiler command, using GCC 4.1.2 (CentOS 5) cause the error:

gcc -g -I. --verbose -c -o hello.o -DLONG_INCLUDE hello.c

or this one that does not cause the error

gcc -g -I. --verbose -c -o hello.o hello.c

Code:

/* hello2.h */

#ifdef _cplusplus
extern "C" {
#endif

int myFunc(int *a);

#ifdef _cplusplus
}
#endif



/* hello.c */
#include <stdio.h>
#include <string.h>
typedef signed char int8_t;
#ifdef LONG_INCLUDE
#include "/usr/include/sys/types.h"
#else
#include <sys/types.h>
#endif
#include "hello.h"


int myFunc(int *a)
{

  if (a == NULL)
    return -1;

  int b = *a;

  b += 20;

  if (b > 80)
    b = 80;

  return b;
}

Thank you

UPDATE:

After looking at preprocessor output via gcc -E it looks like when specifying the full path, gcc does not treat it as a system include path and that, somehow, is contributing (causing?) the error. Tries to use the -isystem option for /usr/include and /usr/include/sys but to no avail.

Upvotes: 1

Views: 786

Answers (1)

Daniel Fischer
Daniel Fischer

Reputation: 183988

In Glibc's <sys/types.h>, the typedefs for int8_t etc. are guarded by

#if !__GNUC_PREREQ (2, 7)

/* These types are defined by the ISO C99 header <inttypes.h>. */
# ifndef __int8_t_defined
#  define __int8_t_defined
typedef char int8_t;
typedef short int int16_t;
typedef int int32_t;
#  if __WORDSIZE == 64
typedef long int int64_t;
#  elif __GLIBC_HAVE_LONG_LONG
__extension__ typedef long long int int64_t;
#  endif
# endif

so a workaround for the problem would be to define the guarding macro on the command line, passing -D__int8_t_defined in addition to -DLONG_INCLUDE.

Upvotes: 1

Related Questions