c++libmemcached

error: multiple types in one declaration in header define declaration


Github In order to compile a project (sprout), I have to compile libmemcached first. During compilation it generates a config.h file, which is from config.ac I think. However, this config.h causes problem:

make  all-am
make[1]: Entering directory `/home/tiina/clearwater/sprout/modules/libmemcached'
  CXX      libhashkit/libhashkit_libhashkit_la-aes.lo
In file included from ./libhashkit/common.h:40:0,
                 from libhashkit/aes.cc:38:
./config.h:632:20: error: multiple types in one declaration
 #define off_t long int
                    ^
./config.h:632:20: error: declaration does not declare anything [-fpermissive]
./config.h:658:17: error: multiple types in one declaration
 #define ssize_t int
                 ^
./config.h:658:17: error: declaration does not declare anything [-fpermissive]
./config.h:635:15: error: multiple types in one declaration
 #define pid_t int
               ^
./config.h:635:15: error: declaration does not declare anything [-fpermissive]
make[1]: *** [libhashkit/libhashkit_libhashkit_la-aes.lo] Error 1
make[1]: Leaving directory `/home/tiina/clearwater/sprout/modules/libmemcached'

This is config.h:

628 /* Define to rpl_malloc if the replacement function should be used. */
629 #define malloc rpl_malloc
630
631 /* Define to `long int' if <sys/types.h> does not define. */
632 #define off_t long int
633
634 /* Define to `int' if <sys/types.h> does not define. */
635 #define pid_t int
636
637 /* Define to rpl_realloc if the replacement function should be used. */
638 #define realloc rpl_realloc
657 /* Define to `int' if <sys/types.h> does not define. */
658 #define ssize_t int

It does not meet this problem in Ubuntu:

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.3.0-17ubuntu1~20.04' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-9-HskZEa/gcc-9-9.3.0/debian/tmp-nvptx/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)

It has this problem in CentOS:

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)

UPDATE: as @n. 1.8e9-where's-my-share m. suggested, I digged deeper.

#include <stdio.h>
#define off_t long int
int main() {
   int a = 1;
   int b = a++;
   return 10;
}

above code compiles, and g++ -E -P results OK1 Then I exchange include and define declaration:

#define off_t long int
#include <stdio.h>

above code does not compile, and g++ -E -P results ERROR Then I deleted define decalration, it compiles again, and results OK2.

diff OK1 ERROR

output:

173c173
< typedef __off_t off_t;
---
> typedef __off_t long int;
diff OK1 OK2

output empty (OK1 and OK2 are the same). Then I released that VIM marked off_t the same color as long or int. Maybe off_t is a reserved keyword? Then I changed off_t with offt:

#define offt long int
#include <stdio.h>

it compiles again.


Solution

  • The configuration script that produces config.h is faulty.

    631 /* Define to `long int' if <sys/types.h> does not define. */
    632 #define off_t long int
    

    This would be fine if off_t was't defined anywhere on your system. But it is defined and used by the system headers, most likely like this:

    typedef long int __off_t;
    typedef __off_t off_t;
    

    The #define wreaks these definitions, making them syntactically invalid.

    The simplest way to fix the problem is to manually remove the offending #defines from config.h and make sure sys/types.h is included.