Skip to content

Duplicate definition with C "typedef struct foo foo" #543

@Shamino0

Description

@Shamino0

The following concept is perfectly valid C code:

typedef struct foo_t {
   int bar;
} foo_t;

For a C++ project, of course, the typedef is redundant, but for a C project, it is not. foo_t and struct foo_t are two distinct items.

Doxygen renders this correctly, putting the foo_t documentation in a "Typedef Documentation" section and struct foo_t in a "Data Structures" section. The typedef has a link to the structure.

When I use Breathe to embed the header's documentation into a Sphinx file with

.. doxygenfile:: foo.h
   :project: MYPROJECT

it generates a warning, saying that foo_t is a duplicate definition:

.../mydoc.rst: 9: WARNING: Duplicate declaration, foo_t

In the Sphinx-generated HTML output, I do see the two items listed in their proper sections. foo_t in the "Typedefs" section and struct foo_t in the (unlabeled) structures section, but I can only link to the typedef. References to :c:type:`foo_t` correctly links to the foo_t typedef, but references to :c:struct:`foo_t` links to the same location (it should link to the struct foo_t structure).

This problem does not happen if the struct and the typedef use different symbols:

typedef struct foo_s {
   int bar;
} foo_t;

but I shouldn't have to make such a change in my code. It is perfectly valid C for the struct name and the typedef name to be the same.

I also understand that this should be a problem in C++, where the typedef is redundant. But I've explicitly configured Breathe to use the C domain, so it should know that this is not C++ code:

breathe_domain_by_extension = { "h" : "c" }

Somewhere in Breathe, the code does not distinguish between different C language constructs that share the same name. For example, all of the following are distinct language elements:

  • typedef ... foo_t - referenceable via :c:type:`foo_t`
  • struct foo_t - referenceable via :c:struct:`foo_t`
  • union foo_t - referenceable via :c:union:`foo_t`
  • enum foo_t - referenceable via :c:enum:`foo_t`

I'm not sure what the best fix is, but please see if there is something that can be done.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugProblem in existing code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions