Getting around compound literals in C++ to removing the warning - 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.

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.

Related

Why does this code behave differently on C-stdio function overloads? (vfprintf vs. putchar)

I'm trying to define various functions with the same name as C stdio to prevent unwanted usage. I encountered an odd situation where the technique works on some functions, but not others. I cannot explain why A::fn calls the stdio version of vfprintf instead of the function definition in the A namespace.
#include <stdio.h>
#include <stdarg.h>
namespace A {
template <typename... Ts>
void putchar(int ch) {
static_assert(sizeof...(Ts) == -1);
}
template <typename... Ts>
void vfprintf(FILE* file, const char* fmt, va_list vlist) {
static_assert(sizeof...(Ts) == -1);
}
void fn(const char* fmt, ...)
{
putchar('A'); // fails to compile (as expected)
va_list vlist;
va_start(vlist, fmt);
vfprintf(stdout, "Hello!\n", vlist); // does not fail (not expected)
va_end(vlist);
}
}
int main()
{
A::fn("hello");
return 0;
}
P.S. Happy to hear comments indicating that there is a better way to restrict C-style I/O (maybe clang-tidy).
Replacing standard library routines is UB (citation to follow). See examples here and here for the kind of trouble this can cause.
Edit: OK, here's the promised citation:
The C++ standard library reserves the following kinds of names:
...
names with external linkage
...
If a program declares or defines a name in a context where it is reserved, other than as explicitly allowed by [library], its behavior is undefined.
But, as discussed in the comments, I'm not sure whether you're doing this in a permitted context or not (although, on reflection, I don't think you are), so I'm going to change tack.
There is, in fact, a very simple way to do what you want. You can do this with #pragma GCC poison. So, taking your example, all you need is:
#pragma GCC poison putchar vfprintf
and you're done. clang also supports this pragma.
Live demo.
Hats, rabbits, we can do it all :) (on good days)

Stubbing a C function that has a a parameter with the same name in C++

int stat(const char *__restrict__ __file, struct stat *__restrict__ __buf);
This function needs to be stubbed in order to cover more branches in an unit test made using Google Unit Test.
In file stubs.h
I have to stub this function, so I provide the following prototype:
int stat_stub(const char *__restrict__ __file, struct stat *__restrict__ __buf);
Followed by:
#define stat stat_stub
int stat_RET;
Implementation in stubs.c
int stat_stub(const char *__restrict__ __file, struct stat *__restrict__ __buf)
{
return stat_RET;
}
The problem is that the define also replaces struct stat with struct stat_stub, and this causes a multitude of errors to appear when compiling.
I would like to know if there is a workaround to this issue, as I am currently stuck on it.
You can use a macro with parameters.
#define stat(p1,p2) stat_stub(p1,p2)
You don't have to use macros at all, instead you can make it differ in build system.
Remove stubs.h and only use real header in production code.
In stubs.c define function with the same name:
int stat(const char *__restrict__ __file, struct stat *__restrict__ __buf)
{
return stat_RET;
}
Now, when building production target, you link real implementation. For UT target, you build and link stubs.c.
This solution will be more versatile than macros and easier to maintain.
The root of all your problems is that you name types and functions the same thing. Simply don't do that, unless this is a C++ constructor. It doesn't look like one. The only reason this code compiles in C, is because C uses different namespaces for struct tags and function identifiers.
The solution to all your problems is not to use macros or other work-arounds, but to implement a coding standard for how you name types and functions.

BOOST_AUTO And C++ User Defined Type

I'm new to BOOST_AUTO and here is a basic question.
I defined my own class and used it with BOOST_AUTO. According to the tutorial:
If your define your own type, the Typeof Library cannot handle it
unless you let it know about this type. You tell the Typeof Library
about a type (or template) by the means of "registering" this
type/template.
But my code below doesn't register anything and runs correctly in VC++2010. Is this registration really necessary. Did I do anything wrong?
#include <boost/typeof/typeof.hpp>
using namespace std;
namespace NS1 {
struct X {
X(const X& x){s=x.s+1;}
X(){s=3;}
int s;
};
}
int _tmain(int argc, _TCHAR* argv[])
{
NS1::X x;
BOOST_AUTO(y,x);
cout << y.s << endl;
return 0;
}
output:4
from the docs:
The BOOST_AUTO macro emulates the proposed auto keyword in C++.
looking into the code it seems they replace BOOST_AUTO to BOOST_TYPEOF.
typeof seems to be the old extension name of decltype in GCC compilers.
(See this SO question). The code of the boost typeof library doesn't use the auto keyword apparantly for msvc (See here).
It seems that at the time of writing this library, there were some compilers who did support the auto keyword while others did not. If you want to compile the code on architectures that don't support this feature, the registration is necessary.
In any case, since C++11 is released for a while by now. Using this library if you compiler already supports the auto keyword should be considered bad practise, because this library only exists to emulate the proposed feature.
Except of course you have to compile to C++03 for some reason.

portable way of checking parameters against printf format in compile time, C++

I have a log function my_log(const char* my_fmt, ...) doing customized logging. I would like my_log to follow the C printf convention. To save me troubles, I'd like to warn users of any warning and error printf() would give. The printf feature I need is -Wformat warning. And errors of course.
Question: How can I achieve this without any runtime overhead? (not using compiler specific feature).
In GCC, I can use __attribute__((format())).
void __attribute__((format(printf,1,2))) my_log(const char* fmt, ...){ }
For now, I need to compile on Intel C++ compiler (ICC) and GCC. If I could achieve the attribute checking in ICC, that would be good. If there were a pure C++ language trick to do such checking at compile-time, that would be awesome.
There is no portable way to do this. Even for the printf family the language lets the compiler assume you know what you're doing and compile what you've written although g++ does provide a helpful warning if you enable it.
Since your project is C++ why not use a C++ idiom and use boost::format (http://www.boost.org/doc/libs/1_57_0/libs/format/doc/format.html) or IO streams? Then you get type safety and don't need to even worry about validating the input.
As other answers said, there is no portable/standard way to achieve what the question asks for. However, the Intel C/C++ compilers (icc and icpc) are 100% compatible with GNU function attributes. See Intel XE13. icpc does give the -Wformat warnings when I declare __attribute__((format())).
There is no portable way to do it.
You can use variadic templates to check arguments at runtime, but it will slow down the my_log().
Also, you can try following solution, but then my_log() will not follow the printf convention.
#include <iostream>
#include <initializer_list>
#include <sstream>
class UC
{
static std::stringstream ss;
std::string str;
friend const char *Str(std::initializer_list<UC> data);
public:
template <class T> UC(T param) : str((ss.str(""), ss << param, ss.str())) {}
};
std::stringstream UC::ss;
void my_log(std::initializer_list<UC> data)
{
std::string in_str;
for (auto it = data.begin(); it != data.end(); it++)
ret += it->str;
std::cout << in_str.c_str() << '\n'; // Or whatever you want to do with your string.
}
int main()
{
my_log({"Hello", '!', 11});
}

Calling C++ (not C) from Common Lisp?

I am wondering if there is some way to call C++ code from Common Lisp (preferably portably, and if not, preferably in SBCL, and if not, well, then Clozure, CLisp or ECL).
The C++ would be called inside loops for numeric computation, so it would be nice if calls were fast.
CFFI seems to not support this:
"The concept can be generalized to
other languages; at the time of
writing, only CFFI's C support is
fairly complete, but C++ support is
being worked on."
(chapter 4 of the manual)
SBCL's manual doesn't mention C++ either; it actually says
This chapter describes SBCL's
interface to C programs and libraries
(and, since C interfaces are a sort of
lingua franca of the Unix world, to other programs and libraries in
general.)
The C++ code uses OO and operator overloading, so it really needs to be compiled with g++.
And as far as I know, I can have a C++ main() function and write wrappers for C functions, but not the other way around -- is that true?
Anyway... Is there some way to do this?
Thank you!
After compiling, most C++ functions actually boil down to regular C function calls. Due to function overloading and other features, C++ compilers use name mangling to distinguish between similarly named functions. Given an object dump utility and sufficient knowledge about your C++ compiler, you can call C++ code directly from the outside world.
Having said that though, you may find it easier to write a C-compatible layer between Lisp and your C++ code. You would do that using extern "C" like this:
extern "C" Foo *new_Foo(int x)
{
return new Foo(x);
}
This makes the new_Foo() function follow the C calling convention so that you can call it from external sources.
The main difference in calling C++ functions instead of C functions apart from the name mangling are the 'hidden' features like this pointers that are implicitly passed to member functions. The C runtime layer doesn't know anything about these, implicit type conversions and other fun C++ features, so if you intend to call C++ through a C interface, you might have to fake these features if necessary.
Assuming that you can hold at least a void * to the object you intend to call and the data it requires, you can degrade the following C++ call
matrix->multiply(avector);
to a C call if you create a C wrapper function:
extern "C"
void matrix_multiply(void *cpp_matrix, void *cpp_vector) {
reinterpret_cast<matrix_type *>(cpp_matrix)->multiply(reinterpret_cast<vector_type *>(cpp_vector);
}
Obviously the function matrix_multiply would sit in the C++ source code and compiled as such but it does expose a C interface to the outside world. As long as you can interact with the opaque pointers, you're OK with the translation shims above.
Admittedly this is not necessarily the most elegant solution for a problem like this but I've used it in the past in situations like yours.
The other option would be to make the C++ calls directly by treating them as C calls with additional parameters and supplying all the required information yourself, but that does move you into the realm of compiler-specific code very quickly. Basically, you would still be holding the opaque pointers to C++ objects, but you'd have to work out the mangled name of the function you want to call. Once you've got that function name, you'll have to supply the this pointer (which is implicit in C++ and semi-implicit in the example above) and the correct parameters and then call the function. It can be done but as mentioned, puts you deeply in to the realm of compiler and even compiler-version specific behaviour.
Oh, wait!
It seems that there is a trick I can use!
I write a wrapper in C++, declaring wrapper functions extern "C":
#include "lib.h"
extern "C" int lib_operate (int i, double *x) {
...
}
The header file lib.h, which can be called from both C and C++, is:
#if __cplusplus
extern "C" {
#endif
int lib_operate (int i, double *x);
#if __cplusplus
}
#endif
Then compile with:
g++ -c lib.cpp
gcc -c prog.c
gcc lib.o prog.o -lstdc++ -o prog
Seems to work for a toy example! :-)
So, in Common Lisp I'd call the wrapper after loading libstdc++.
Anyway, thank you for your answers!
Update 2021:CL-CXX-JIT which handles most of the work on the lisp side.
Example:
(ql:quickload :cxx-jit)
(in-package cxx-jit)
(from '("<cmath>") 'import '("static_cast<double(*)(double)>(std::sin)" . "cpp-sin"))
(cpp-sin 0d0)
(from nil 'import "struct C{ auto hi(){return \"Hello, World\\n\";} auto bye(){return \"Bye\";} };" '("&C::bye" . "bye") '("&C::hi" . "hi") '("[](){static C x; return x;}" . "cc"))
(cc)
(hi *)
(bye **)
You can use cl-cxx which is like writing pybind11 for python.
example in c++ 'std >= c++14', compiled as shared lib:
#include <string>
#include "clcxx/clcxx.hpp"
class xx {
public:
xx(int xx, int yy) : y(yy), x(xx) {}
std::string greet() { return "Hello, World"; }
int y;
int x;
};
std::string greet() { return "Hello, World"; }
int Int(int x) { return x + 100; }
float Float(float y) { return y + 100.34; }
auto gr(std::complex<float> x) { return x; }
std::string hi(char* s) { return std::string("hi, " + std::string(s)); }
void ref_class(xx& x) { x.y = 1000000; }
CLCXX_PACKAGE TEST(clcxx::Package& pack) {
pack.defun("hi", F_PTR(&hi));
pack.defun("test-int", F_PTR(&Int));
pack.defun("greet", F_PTR(&greet));
pack.defun("test-float", F_PTR(&Float));
pack.defun("test-complex", F_PTR(&gr));
pack.defun("ref-class", F_PTR(&ref_class));
pack.defclass<xx, false>("xx")
.member("y", &xx::y)
.defmethod("greet-from-class", F_PTR(&xx::greet))
.constructor<int, int>();
}
usage in lisp:
(cffi:use-foreign-library my-lib)
(cxx:init)
(cxx:add-package "TEST" "TEST")
(test:greet)
(setf my-class (test:create-xx2 10 20))
(test:y.get myclass)
That would take care of all conversions, extern "C", ... for you.
Depending on your C++ ABI, your wrapper (lib_operate above) might need to somehow handle any C++ exceptions that might occur. If your ABI does table-drive exception handling, unhandled exceptions will simply crash the (Lisp) process. If it instead does dynamic registration, you might not even notice that anything went wrong. Either way, it's bad.
Or, if you've got the no-throw guarantee for the wrapped code, you can ignore all this.