1

我在头文件中有这一行:

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)。

这里有什么问题?这种类型的typedefC 的新特性是没有在编译器中实现,还是像这些常见的编译器差异?

编辑:实际上 struct 是在 .c 文件中定义的,而不是 .cpp 文件。添加了显示使用 Ubuntu clang 编译Makefilemake输出,以及带有麻烦typedef语句的头文件顶部。最后运行一个测试,所有 105 个测试都通过。

Edit2:请参阅 Jonathan Leffler 的回答,了解此方法有效与无效的情况。

环形缓冲区.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++。

4

1 回答 1

2

如果您没有尝试使用typedef指针类型,您的代码在 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++ 中编译。等效的 C main()using<stdio.h>将在 C 中工作。

于 2017-02-17T03:58:32.850 回答