Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting around compound literals in C++ to removing the warning

Tags:

c++

I'm working with libsystemd-dev (a C library) in my C++ application.

I get a gcc/clang pedantic warning

compound literals are a C99-specific feature

with this code:

#include <systemd/sd-bus.h>

void foo()
{
  sd_bus_error err = SD_BUS_ERROR_NULL;  // compound literals are a C99-specific feature
  ...
}

Looking at the <systemd/sd-bus.h> header file, I see:

typedef struct {
        const char *name;
        const char *message;
        int _need_free;
} sd_bus_error;

#define SD_BUS_ERROR_MAKE_CONST(name, message) ((const sd_bus_error) {(name), (message), 0})
#define SD_BUS_ERROR_NULL SD_BUS_ERROR_MAKE_CONST(NULL, NULL)

This means I can solve the warning with:

#include <systemd/sd-bus.h>

void foo()
{
  sd_bus_error err = {nullptr, nullptr, 0};
  ...
}

But is that a good idea? If the library changes, my code would need to change too so I feel that it's volatile. Is there really any problem with this warning? Is there a better way to get around it?

There is always the method of just using compiler flags to disable the warning, but I was wondering if there could be an encouraged method in-code to address this.

like image 274
Stewart Avatar asked Jun 17 '19 07:06

Stewart


People also ask

What is a compound literals in C?

In C, a compound literal designates an unnamed object with static or automatic storage duration. In C++, a compound literal designates a temporary object that only lives until the end of its full-expression.

Does C++ have compound literals?

In C++, a compound literal designates a temporary object, which only lives until the end of its full-expression. As a result, well-defined C code that takes the address of a subobject of a compound literal can be undefined in C++, so the C++ compiler rejects the conversion of a temporary array to a pointer.


1 Answers

Omnifarious already hinted at one approach - use extensions inside a wrapper function. The slightly more robust method is to use an extern "C" wrapper function, in its own Translation Unit. Compile that whole Translation Unit as C11, without extensions.

This is generally more robust. Mixing code at source level requires advanced compiler support, whereas linking C and C++ is fairly straightforward.

like image 73
MSalters Avatar answered Oct 11 '22 02:10

MSalters