I have this line in a header file:
typedef struct mystruct *mystruct;
And the corresponding struct definition in a .c file. Pretty standard practices.
I am getting this compilation error:
fatal error: typedef redefinition with different types ('struct mystruct *' vs mystruct')
This is using the Hexagon Tools Compiler (7.2.12) from Hexagon 3.0 SDK. It is officially QuIC LLVM Hexagon Clang version 7.2.12. Building for Snapdragon Flight. This should work as far as I know. It works with Ubuntu clang version 3.5.0-4ubuntu2~trusty2 (based on LLVM 3.5.0) for x86_64-pc-linux-gnu.
What is wrong here? Is this type of typedef
a newer feature of C that is not implemented in the compiler, or rather are compiler differences like these common?
Edit: Actually struct is defined in a .c, not .cpp, file. Added the Makefile
and make
output showing compilation with Ubuntu clang, as well as the top of the header file with the troublesome typedef
statment. A test is run at the end, and all 105 tests pass.
Edit2: See Jonathan Leffler's answer for cases where this works vs doesn't work.
ringbuf.h:
#include <stddef.h>
#include <sys/types.h>
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
typedef struct ringbuf_t *ringbuf_t;
Makefile:
CC=clang
CFLAGS=-O0 -g -Wall -Wpointer-arith -ftrapv -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error
# or, for gcc...
#CC=gcc
#CFLAGS=-O0 -g -Wall
LD=$(CC)
LDFLAGS=-g
test: ringbuf-test
./ringbuf-test
coverage: ringbuf-test-gcov
./ringbuf-test-gcov
gcov -o ringbuf-gcov.o ringbuf.c
valgrind: ringbuf-test
valgrind ./ringbuf-test
help:
@echo "Targets:"
@echo
@echo "test - build and run ringbuf unit tests."
@echo "coverage - use gcov to check test coverage of ringbuf.c."
@echo "valgrind - use valgrind to check for memory leaks."
@echo "clean - remove all targets."
@echo "help - this message."
ringbuf-test-gcov: ringbuf-test-gcov.o ringbuf-gcov.o
gcc -o ringbuf-test-gcov --coverage $^
ringbuf-test-gcov.o: ringbuf-test.c ringbuf.h
gcc -c $< -o $@
ringbuf-gcov.o: ringbuf.c ringbuf.h
gcc --coverage -c $< -o $@
ringbuf-test: ringbuf-test.o libringbuf.so
$(LD) -o ringbuf-test $(LDFLAGS) $^ -L$(MY_LIBS_PATH) -lringbuf
ringbuf-test.o: ringbuf-test.c ringbuf.h
$(CC) $(CFLAGS) -c $< -o $@
libringbuf.so: ringbuf.o
$(CC) -shared -o libringbuf.so ringbuf.o
cp ./libringbuf.so $(MY_LIBS_PATH)/
ringbuf.o: ringbuf.c ringbuf.h
$(CC) $(CFLAGS) -fPIC -c $< -o $@
cp ./ringbuf.h $(MY_INCLUDES_PATH)/
clean:
rm -f ringbuf-test ringbuf-test-gcov *.o *.so *.gcov *.gcda *.gcno
.PHONY: clean
make
output:
clang -O0 -g -Wall -Wpointer-arith -ftrapv -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -c ringbuf-test.c -o ringbuf-test.o
clang -O0 -g -Wall -Wpointer-arith -ftrapv -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -fPIC -c ringbuf.c -o ringbuf.o
cp ./ringbuf.h /home/eric/Includes/
clang -shared -o libringbuf.so ringbuf.o
cp ./libringbuf.so /home/eric/Libs/
clang -o ringbuf-test -g ringbuf-test.o libringbuf.so -L/home/eric/Libs -lringbuf
./ringbuf-test
Edit3: This actually works fine with just the Hexagon-clang compiler. It is the compilation process of the larger program that this module exists in that is being problematic. I think that it is attempting to compile this code as C++.