2

I was working on a wayland compositor based on C++. My project uses wlroots which is a C Library. I have a set of header files in wlroots which i need to add to my C++ project. I used extern "C" to include c header files but it was showing errors on 'static' type.

/usr/local/include/wlr/render/wlr_renderer.h:72:27: error: expected primary-expression before ‘static’
   72 |         const float color[static 4], const float projection[static 9]);
      |                           ^~~~~~

Here is the sample code for reference :

#ifndef SERVER_HPP
#define SERVER_HPP

#include <wayland-server.h>

extern "C"
{
    #include <wlr/backend.h>
    #include <wlr/render/allocator.h>
    #include <wlr/render/wlr_renderer.h>
    #include <wlr/types/wlr_compositor.h>
};


class Server
{
    public:
        struct wl_display *wl_display;
        struct wl_event_loop *wl_event_loop;

        struct wlr_backend *backend;
        struct wlr_renderer *renderer;
        struct wlr_allocator *allocator;
        struct wlr_compositor *compositor;

    public:
        bool init();
        bool run();
        void terminate();
};

#endif

I did some digging and find out a way to fix it. by this method:

#define static

extern "C"
{
    #include <wlr/backend.h>
    #include <wlr/render/allocator.h>
    #include <wlr/render/wlr_renderer.h>
    #include <wlr/types/wlr_compositor.h>
};

#undef static

But i am not sure whether it will cause any issues in the future. This seems to be a hack method. Is there any better method to overcome this?

Barmar
  • 741,623
  • 53
  • 500
  • 612
trickymind
  • 557
  • 5
  • 21
  • 3
    `extern "C"` doens't make the C++ compiler parse it in C syntax, it just affects the linkage. `[static 4]` is a C feature that isn't in C++. https://stackoverflow.com/questions/18362315/static-size-of-array-in-c99 – Barmar Apr 22 '22 at 16:53
  • is there any other way to overcome this issue. some other compositors like wayfire was able to do it. but i don't understand how. – trickymind Apr 22 '22 at 16:54
  • 1
    `static` is a [keyword](https://en.cppreference.com/w/cpp/keyword). You are not allowed to redefine keywords in C++ (or C, not that it matters in this case) so you're going to have to wrap this C code to make it palatable in C++ and compile it in C – user4581301 Apr 22 '22 at 16:55
  • can you please tell how can i do that. – trickymind Apr 22 '22 at 16:57
  • 2
    Speaking of, if your intention is to use pointer to structures, you don't need to include the C library headers in your public C++ headers. Forward declared types will work and reduce header bloat. – StoryTeller - Unslander Monica Apr 22 '22 at 16:58
  • Ignore my comment about wrapping. StoryTeller's got a much better path forward. – user4581301 Apr 22 '22 at 16:59
  • Thank you all, i solved the issue by adding #define _GNU_SOURCE 1 to the header file. now it is compiling. – trickymind Apr 22 '22 at 17:03
  • i think this has something to do with the POSIX. i am not sure about it, how ever it is working.let me try to do some more digging on it. – trickymind Apr 22 '22 at 17:10
  • sorry please don't go for the recent answer i posted, i forgot to remove the #define static from the source code before compiling. The issue still exist. :( – trickymind Apr 22 '22 at 17:14
  • Rats. That looked like a nice, clean solution. Looks like you're back to forward-declaring opaque types like StoryTeller suggested. – user4581301 Apr 22 '22 at 17:23
  • i looked into wayfire sources and seen the same #define static there too, https://github.com/WayfireWM/wayfire/blob/master/src/api/wayfire/nonstd/wlroots-full.hpp – trickymind Apr 22 '22 at 17:25
  • @user4581301 can you show an example of this forward declaration that you have mentioned, i am not that good in c++ – trickymind Apr 22 '22 at 17:27
  • 1
    This one is simple: Remove the include files that are giving you grief and add `struct wl_display;` and friends, or whatever declarations are missing, to server.hpp right above the `class Server` declaration. If all you need is pointers or references to the types and never go looking at the data in the types, all you need to know is the type exists and is defined before its innards are actually needed and used. – user4581301 Apr 22 '22 at 17:32
  • 1
    Redefining `static` is illegal and can blow up in your face. Say a year from now someone adds new, c++-allowed use of the `static` keyword to one of the headers. The hack will fail. And that's assuming the compiler doesn't flip out over the illegally redefined keyword and decide to generate a program that hacks the Pentagon and launches a nuclear strike on your house. – user4581301 Apr 22 '22 at 17:47
  • Thank you @user4581301, i will check it out. – trickymind Apr 23 '22 at 09:01

0 Answers0