我在头文件中有这一行:
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飞行建设。据我所知,这应该有用。适用于x86_64-pc-linux-gnu的Ubuntu clang版本3.5.0-4ubuntu2~trusty2(基于LLVM 3.5.0)。
这里有什么问题?这种类型的typedef
是否是编译器中没有实现的C的新特性,或者更像是这些常见的编译器差异?
编辑:实际上,struct是在.c而不是.cpp文件中定义的。添加了显示使用Ubuntu clang编译的Makefile
和make
输出,以及带有麻烦的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 ++。
答案 0 :(得分:2)
如果您没有尝试Use typedef
for a pointer type,那么您的代码在C和C ++中会没问题。
标题(例如hdr.h
)可以/应该包含:
typedef struct mystruct mystruct;
源(例如hdr.cpp
)可以包含:
#include "hdr.h"
struct mystruct
{
const char *a;
int b;
int c;
};
#include <iostream>
int main()
{
mystruct *ap = new mystruct;
ap->a = "collywobbles";
ap->b = 1;
ap->c = 2;
std::cout << "a: " << ap->a << ", b = " << ap->b << ", c = " << ap->c << "\n";
return 0;
}
即使在严格的警告下,这也将在C ++中编译。使用main()
的等效C <stdio.h>
可以在C中使用。