I have this piece of code here and I get a GCC error: Redefinition of union semun right at the beginning of this code
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
};
This program is about communicating with mutexes. I don't think that it's about the other parts of the program because the error comes here, right at the first line of it, and this code is outside the main, at the beginning of the program so there's not any other union declaration before (and after). Thank you
Contrary to X/Open, some platforms define union semun in their headers (specifically in sys/sem.h).
You can check accordingly using appropriate platform identifier macros:
#if (defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)) \
|| defined(__FreeBSD__) || ...
/* union semun is defined by including <sys/sem.h> */
#else
union semun {
// ...
};
#endif
If you have a meta-make system for your package (configure, CMake, etc.) you might check for the existence of union semun at the configure stage instead of relying on platform checks.
Related
I am trying to generate some pb.c and pb.h files using protobuf-c. I have earlier use nanopb to generate the same files but need to move to protobuf-c for a new project.
When generating the structure for a OneOf field, I see a difference in the generated files.
For the following definition in the proto file:
message MetricValue {
oneof value {
bool aBoolean = 1;
string aString = 2;
uint32 anInteger = 3;
float aFloat = 4;
double aDouble = 5;
}
}
Nanopb generates the following:
typedef struct _MetricValue {
pb_size_t which_value;
union {
bool aBoolean;
char aString[32];
uint32_t anInteger;
float aFloat;
double aDouble;
} value;
/* ##protoc_insertion_point(struct:MetricValue) */
} MetricValue;
while using protobuf-c generates the following:
struct MetricValue
{
ProtobufCMessage base;
MetricValue__ValueCase value_case;
union {
protobuf_c_boolean aboolean;
char *astring;
uint32_t aninteger;
float afloat;
double adouble;
};
};
The way my project is configured, the build is unsuccessful with the following error:
"An anonymous member in a struct is an extension to C (AnonymousMember)". I am aware that I can suppress this with some compile flags but the way the rest of the code is written, using an anonymous union will cause significant changes to my code.
Is there a way where I can force protobuf-c to not generate anonymous members?
Looking at the protobuf-c source code in c_message.cc, the generation of union {} is unconditional and has no option for naming it.
My static code analysis has found a bug in my code. I try to send an empty message:
mq_send(mqId, 0, 0, 1);
It says, the message buffer (parameter 2) should not be 0. It says this because the header says so:
glibc-2.29/rt/mqueue.h
/* Add message pointed by MSG_PTR to message queue MQDES. */
extern int mq_send (mqd_t __mqdes, const char *__msg_ptr, size_t __msg_len,
unsigned int __msg_prio) __nonnull ((2));
glibc-2.29/sys/cdefs.h
/* The nonull function attribute allows to mark pointer parameters which
must not be NULL. */
#if __GNUC_PREREQ (3,3)
# define __nonnull(params) __attribute__ ((__nonnull__ params))
#else
# define __nonnull(params)
#endif
I know how to fix this. I just wonder: is this correctly implemented in glibc?
Neither linux man nor the posix standard says anything about passing a nullpointer. No error code or undefined behavior is described. In fact, when the length is 0, a null pointer is totally valid and works!
I working on an old module for kernel 2.4.x and want to rewrite it for kernel 4.15.0.19.
There is a declaration which is causing an error during the compilation:
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
I checked in the newer kernel and tcp_opt struct is not defined anywhere, neither tp_pinfo union nor af_tcp.
From 2.4.x kernel, it is declared inside struct sock as follows:
union {
struct tcp_opt af_tcp;
#if defined(CONFIG_INET) || defined (CONFIG_INET_MODULE)
struct raw_opt tp_raw4;
#endif
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
struct raw6_opt tp_raw;
#endif /* CONFIG_IPV6 */
#if defined(CONFIG_SPX) || defined (CONFIG_SPX_MODULE)
struct spx_opt af_spx;
#endif /* CONFIG_SPX */
} tp_pinfo;
What is the purpose of the first initialisation (in the beginning of the question) and how is this replaced in the newer kernels?
EDIT:
I managed to solve this using:
const struct tcp_sock *tp = tcp_sk(sk);
And then accessing the TCP Options in this way:
tp->rx_opt.rcv_tsval
Just installed MPLAB X and imported a project I'm working on. I got this error, and because it's an application library file, I'm not too keen on modifying it. The code it refers to is:
// BDT Entry Layout
typedef union __BDT
{
union
{
struct
{
BYTE CNT __attribute__ ((packed));
BD_STAT STAT __attribute__ ((packed));
};
struct
{
WORD count:10; //test
BYTE :6;
WORD ADR; //Buffer Address
};
};
DWORD Val;
WORD v[2];
} BDT_ENTRY;
I'd like to know how to modify this or my settings so that I can compile. I do not get this error in MPLAB.
__attribute__ ((packed)) is safe to comment out.
// BDT Entry Layout
typedef union __BDT
{
union
{
struct
{
BYTE CNT ; //__attribute__ ((packed)); suppress compiler warnings
BD_STAT STAT __attribute__ ((packed));
};
struct
{
WORD count:10; //test
BYTE :6;
WORD ADR; //Buffer Address
};
};
DWORD Val;
WORD v[2];
} BDT_ENTRY;
I had to modify the USB hardware abstraction layer to get things to compile.
I have a C code which records a procedure address in an array
void* lpProcAddress[5];
typedef unsigned long (*MyFunction_TYPE) (void*);
#define MyFunctionInArray ( (MyFunction_TYPE) lpProcAddress[0] )
unsigned long AnyFunction ( void* lpPointerToAny )
{
/* Some Code */
return 0;
}
int main()
{
MyFunctionInArray =
AnyFunction; // Displays: "error: lvalue required as left operand of assignment"
}
GCC displays "error: lvalue required as left operand of assignment".
How can I fix this?
For my purpose, I could not call directly AnyFunction().
This will expand to:
(type)xxx = ...
This is not legal. However, you could use something like:
* (type *)& xxx = ...
Try assigning to lpProcAddress[0] directly instead of to MyFunctionInArray.
This should work and you can just keep it that way.
However, if you are interested in why it did not work with your define keep reading, there is a way to do that too:
What you are doing in your #define is cast a pointer-type to MyFunction_TYPE
1) you dont really need to cast the pointer-array to anything, you can just assign the function-pointers into its slots
2) if you really want to cast the pointer-array before assigning into it you have to cast it to a function-pointer-type (and do that before dereferencing so use parenthesis before [0]).
Instead of defining lpProcAddress as void* why not just define as MyFunction_TYPE, e.g.:
typedef unsigned long (*MyFunction_TYPE) (void*);
MyFunction_TYPE lpProcAddress[5];
Then in your main function you can just do:
lpProcAddress[0] = AnyFunction;
Without needing to care about casting.
Likewise to call the function you can then just do:
result = lpProcAddress[0]( some_ptr );