Hexagon编译器遇到`typedef struct mystruct * mystruct`的问题

时间:2017-02-17 02:49:50

标签: c llvm-clang qualcomm hexagon-dsp

我在头文件中有这一行:

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编译的Makefilemake输出,以及带有麻烦的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 ++。

1 个答案:

答案 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中使用。