3

I have got this hpp file:

struct rte_spinlock_t;

class A {

    public:
        void init();
    private:
        rte_spinlock_t* spinlock;
};

and the corresponding cpp file:

#include "A.hpp"

typedef struct {
    int lock;
} rte_spinlock_t;

void A::init()
{

}


Now, compiling like this: g++ A.cpp I get this error:

A.cpp:5:3: error: conflicting declaration ‘typedef struct rte_spinlock_t rte_spinlock_t’
    5 | } rte_spinlock_t;
      |   ^~~~~~~~~~~~~~
In file included from A.cpp:1:
A.hpp:2:8: note: previous declaration as ‘struct rte_spinlock_t’
    2 | struct rte_spinlock_t;
      |        ^~~~~~~~~~~~~~

Obviously making the struct named it works, unfortunately I cannot control the typedef of struct rte_spinlock_t that is in a library.

How could I workaround this?

I expect to be able to forward an unnamed struct without getting into conflicting declaration.

  • 4
    *"I expect to be able to forward an unnamed struct... "* Not possible AFAIK – Jason Dec 13 '22 at 11:39
  • What you have there is an *anonymous struct*. These are not standard C++, so AFAIK you are stuck. I suppose you could use a void pointer and cast when the definition is available. – john Dec 13 '22 at 11:39
  • Is this `rte_spinlock` library C++, or C code? If it's C, I'd wrap it in C++ code in a way avoiding forward-declarations and the reference just the wrapper. – alagner Dec 13 '22 at 11:46
  • 1
    `struct rte_spinlock_t` ≠ `struct` (anonymous). – Eljay Dec 13 '22 at 11:59
  • remove typedef (useless in C++), just write 'struct rte_spinlock_t { int lock; } ;' – jls28 Dec 13 '22 at 11:59
  • @jls28 This is what i suggested before(in my deleted comment) but then noted that OP cannot control the typedef of struct as said in their question. – Jason Dec 13 '22 at 12:26
  • 1
    If this is how the third-party library is structured, you may want to find a better library. If this is not *quite* the third-party code, you may want to show a more faithful representation of it. – n. m. could be an AI Dec 13 '22 at 12:27
  • 1
    @john -- this usage is legal. Microsoft has a notion of an "anonymous struct" that's analogous to an anonymous union, with neither a name nor an object; it's illegal and confusing, but it's not this case. `struct XX { struct { int x; int y; }; };`, you can create an `XX` object and use its `x` and `y` members. Welcome to the wonderful world of Windows! – Pete Becker Dec 13 '22 at 15:09

1 Answers1

3

From what I understand what you have is more-less this (erroneous code): https://godbolt.org/z/zarsTq6oE

Why don't you use pimpl (private implementation) idiom for extra level of indirection and hiding the "gory details"?

Let's assume my X is your A, lib.h contains the troublesome typedef:

//example.cpp
#include "example.hpp"
#include "lib.h"

struct Impl
{
    CStruct* cs;
};

void X::init()
{
    clib_init(&impl->cs);
}

X::X()
{
    impl = std::make_unique<Impl>();
}
X::~X() = default;
//example.hpp
#pragma once
#include <memory>

struct Impl;

struct X
{
    X();
    ~X();

    //rest of special functions omitted for brevity
    //feel free to add them at your own leisure
    void init();
    std::unique_ptr<Impl> impl;

};

Live demo: https://godbolt.org/z/4jYGrYEjr

BTW, I made an assumption that your troublesome struct is C code based on some searching...

alagner
  • 3,448
  • 1
  • 13
  • 25