【发布时间】:2017-07-06 10:12:21
【问题描述】:
我在头文件中有这一行:
typedef struct mystruct *mystruct;
以及 .c 文件中的相应结构定义。相当标准的做法。
我收到此编译错误:
fatal error: typedef redefinition with different types ('struct mystruct *' vs mystruct')
这是使用来自 Hexagon 3.0 SDK 的 Hexagon Tools Compiler (7.2.12)。它的正式版本是 QuIC LLVM Hexagon Clang 版本 7.2.12。为 Snapdragon Flight 建造。据我所知,这应该有效。它适用于 x86_64-pc-linux-gnu 的 Ubuntu clang 版本 3.5.0-4ubuntu2~trusty2(基于 LLVM 3.5.0)。
这里有什么问题?这种类型的typedef 是 C 的一个新特性,没有在编译器中实现,还是像这样的编译器差异很常见?
编辑:实际上 struct 是在 .c 而不是 .cpp 文件中定义的。添加了 Makefile 和 make 输出显示使用 Ubuntu clang 进行编译,以及带有麻烦的 typedef 语句的头文件顶部。最后运行一个测试,所有 105 个测试都通过了。
Edit2:请参阅 Jonathan Leffler 的回答,了解适用与不适用的情况。
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;
生成文件:
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 输出:
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:这实际上只适用于 Hexagon-clang 编译器。存在问题的是该模块存在于较大程序的编译过程。我认为它正在尝试将此代码编译为 C++。
【问题讨论】:
-
您正在重用名称
mystruct。您为什么希望这会起作用? -
此代码在 C++ 中是非法的。您在问题中说“.cpp 文件”。但是您将问题标记为 C。C 和 C++ 是不同的语言。请确定您使用的语言...
-
此外,在 C 中,为结构标记和指向该类型的指针使用相同的名称甚至不是标准做法。当人们确实使用指针类型定义(通常不鼓励)时,他们倾向于对指针类型定义使用某种匈牙利语前缀(例如
pmystruct)。 -
我的错误,已更正为 .c 文件。我没有编写此代码以供参考。从
https://github.com/dhess/c-ringbuf得到它。如有必要,更改 struct typedef 不会太难。但是,这绝对适用于另一个编译器。 -
查看 Jonathan Leffler 的评论,认为这适用于 C 中 (struct, union, enum) 标记周围的命名空间。尽管不适用于 Hexagon clang 编译器
标签: c llvm-clang qualcomm hexagon-dsp