libyang icon indicating copy to clipboard operation
libyang copied to clipboard

Using LYD_VALUE_GET forces to compile with -fpermissive

Open maxrossello opened this issue 2 years ago • 10 comments

I'm using this code, that's similar to what I can see in file binary.c:

const struct lyd_value *value = ... struct lyd_value_binary *data; LYD_VALUE_GET(value, data);

the gcc compiler says:

error: invalid conversion from ‘void*’ to ‘lyd_value_binary*’ [-fpermissive]

I can't find a solution other than adding -fpermissive (which I don't want) because "data" is dereferenced by the macro to know its size, hence I can't pass it as a void*. On the other side, recent versions of gcc don't allow to manipulate the -fpermissive flag locally by using #pragma GCC diagnostic ignored.

maxrossello avatar Feb 19 '24 09:02 maxrossello

What kind of error is that? Why would casting void * to any other kind of pointer be a problem? I believe that is its main purpose, to abstract away from the actual pointer type where needed. So I am not sure how to help you, never seen the error myself.

michalvasko avatar Feb 19 '24 09:02 michalvasko

I agree with you, that was also my understanding from the times of Kernigan and Ritchie. Nevertheless, modern compilers seem not to trust the developer and require an explicit cast, that can be introduced on the left side of assignments in the macro

maxrossello avatar Feb 19 '24 09:02 maxrossello

After a bit of searching, looks like it depends from the fact that I am compiling C++

maxrossello avatar Feb 19 '24 09:02 maxrossello

I see, it is starting to make sense. Yes, I leave out the explicit casts on purpose and leave it up to the implicit cast of C, I did not know C++ does not like that (but it is not surprising). So, it seems the macro should have an explicit cast, perhaps typeof can be used here for that? Please test it (and may even create a PR if you want) and I will then commit it.

michalvasko avatar Feb 19 '24 10:02 michalvasko

Just FYI, in the C++ bindings for libyang, we hit the same problem and simply reimplemented that wrapper. The code is valid C after all, and reimplementing it was a trivial operation that's safe to do because of ABI guarantees.

jktjkt avatar Feb 19 '24 10:02 jktjkt

yes @jktjkt actually I was basically doing the same in origin as a workaround.

The problem with the proposal I envisioned is that casting the left side of the assignment is not possible because it makes it an rvalue. In order to fix it in the C libyang, an #ifdef __cplusplus would be needed I'm afraid, also because anything else would not compile in plain C

maxrossello avatar Feb 19 '24 10:02 maxrossello

this is not easy to solve, because using a template, albeit under #ifdef __cplusplus, also depends not only on the extern "C" statement in the file itself, but also on those in third party including files that would nest in unknown depth.

For the time being I will keep the local rewrite of the wrapper. Thanks a lot for clarification

maxrossello avatar Feb 19 '24 10:02 maxrossello

Maybe I am missing something but why not use typeof, which is supported by C?

michalvasko avatar Feb 19 '24 10:02 michalvasko

Well, according to devdocs it seems it was made official in C23, although it has been a gcc extension for a while.

I also tried to use it anyways, but my gcc complained I was using typeof as an implicitly declared function. I don't know whether there are flags to activate it or if it is because of I am using c++, but it looks anyways too risky in my opinion

maxrossello avatar Feb 19 '24 11:02 maxrossello

I see, okay then. I thought it is a standard (and old) C construct just like sizeof but apparently not.

michalvasko avatar Feb 19 '24 12:02 michalvasko