내가 헤더 파일에이 라인이 있습니다육각 컴파일러`형식 정의 구조체 MYSTRUCT * mystruct`
typedef struct mystruct *mystruct;
그리고 .c 파일에서 해당 구조체 정의를. 꽤 표준적인 관행.
fatal error: typedef redefinition with different types ('struct mystruct *' vs mystruct')
이 육각 3.0 SDK에서 육각 Tools 컴파일러 (7.2.12)을 사용하고 있습니다 :
나는이 컴파일 오류를 얻고있다. 공식적으로 QuIC LLVM Hexagon Clang 버전 7.2.12입니다. 금어초 비행을위한 건물. 이것은 내가 아는 한 작동해야합니다. 그것은 x86_64-pc-linux-gnu에 대한 우분투 clang 버전 3.5.0-4ubuntu2 ~ trusty2 (LLVM 3.5.0 기반)와 함께 작동합니다.
무엇이 잘못 되었나요? 이 유형의 typedef
은 컴파일러에서 구현되지 않은 C의 새로운 기능입니까, 아니면 이러한 일반적인 컴파일러 차이점입니까?
편집 : 실제로 struct는 .cpp 파일이 아니라 .c 파일에 정의되어 있습니다. 문제가있는 typedef
구문을 사용하여 헤더 파일의 맨 위뿐만 아니라 우분투 clang으로 컴파일을 보여주는 Makefile
및 make
출력을 추가했습니다. 테스트가 끝나고 105 개의 테스트가 모두 통과합니다.
편집 2 :이 작동하는 경우 작동하지 않는 경우 조나단 룰러의 대답을 참조하십시오.
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 [email protected]
ringbuf-gcov.o: ringbuf.c ringbuf.h
gcc --coverage -c $< -o [email protected]
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 [email protected]
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 [email protected]
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 : 이것은 실제로 단지 육각 그 소리 컴파일러와 함께 잘 작동합니다. 문제가되는 것은이 모듈이 존재하는 더 큰 프로그램의 컴파일 과정입니다. 나는이 코드를 C++로 컴파일하려고 시도하고 있다고 생각한다.
'mystruct'라는 이름을 다시 사용하고 있습니다. 왜 이것이 효과가 있다고 생각하니? –
이 코드는 C++에서는 유효하지 않습니다. 질문에 ".cpp 파일"이라고 말합니다. 하지만 C와 C++는 다른 언어입니다. 어떤 언어를 사용하고 있는지 결정하십시오. –
또한 struct 태그에 동일한 이름을 사용하고 해당 유형에 대한 포인터를 사용하는 것은 C 언어의 표준 사례조차하지 않습니다. 사람들이 포인터 타입 정의 (일반적으로 권장하지 않음)를 사용할 때, 그들은 pointer typedef에 대해 일종의 헝가리어 접두사 (예 :'pmystruct')를 사용하는 경향이 있습니다. –