The following code resides in a device that will issue a deviceId (LXdeviceInfo) when enumerated through an IrDA sockets connection. This is only important to explain why I would like to keep the data types as similar as possible, but be able to compile using ansi C
With #includes of windows.h and af_irda.h, the following code compiles with no errors in a C++ compiler, but breaks in a C compiler just below the struct assignment (see ERROR here). Ideally I would like to initialize the struct member 'ID' to be an array of characters while keeping it typed just as it is in the original code so I can test the value of LXdeviceInfo just as it would appear when querying it from a call to the device from a PC socket connection.
Is there some way to modify this assignment block to work in straight C?
#include <windows.h>
#include <af_irda.h>
#define IR_HINT_COMPUTER 0x04
#define IR_HINT_EXT 0x80
#define IR_HINT_OBEX 0x20
#define IR_HINT_IRCOMM 0x04
#define IR_CHAR_ASCII 0
#define PROD_FAMILY_NAME ("product name goes here")
#define uint8_t unsigned char
const struct {
uint8_t hint1;
uint8_t hint2;
uint8_t charset;
uint8_t ID[sizeof(PROD_FAMILY_NAME)];
} devInfoStorage =
{
IR_HINT_COMPUTER | IR_HINT_EXT, // hint1
IR_HINT_OBEX | IR_HINT_IRCOMM, // hint2
IR_CHAR_ASCII, // charset
PROD_FAMILY_NAME // Prod ID string
}; // ERROR here: Innvalid initialization type: found 'pointer to char' expected 'unsigned char'
const uint8_t *LXdeviceInfo = (uint8_t *) &devInfoStorage;
/* The size of the device info */
const uint8_t LXdeviceInfoLen = sizeof(devInfoStorage);
void main(void)
{
#define DEVICE_LIST_LEN 10
unsigned char DevListBuff[sizeof (DEVICELIST) -
sizeof (IRDA_DEVICE_INFO) +
(sizeof (IRDA_DEVICE_INFO) * DEVICE_LIST_LEN)];
int DevListLen = sizeof (DevListBuff);
PDEVICELIST pDevList;
pDevList = (PDEVICELIST) & DevListBuff;
//code continues.
}
Yes, you can assign one instance of a struct to another using a simple assignment statement. In the case of non-pointer or non pointer containing struct members, assignment means copy. In the case of pointer struct members, assignment means pointer will point to the same address of the other pointer.
In C, the only operation that can be applied to struct variables is assignment. Any other operation (e.g. equality check) is not allowed on struct variables.
In C/C++, we can assign a struct (or class in C++ only) variable to another variable of same type. When we assign a struct variable to another, all members of the variable are copied to the other struct variable.
If the structures are of compatible types, yes, you can, with something like: memcpy (dest_struct, source_struct, sizeof (*dest_struct)); The only thing you need to be aware of is that this is a shallow copy.
Remove the parentheses around the string literal. The parentheses make the macro expand into an expression that will decay into a pointer type, which makes it not compile in your C compiler. A pointer type cannot be used to initialize an array. Without the parentheses, the string literal is used to initialize the array.
#define PROD_FAMILY_NAME "product name goes here"
The C standard states that a parenthesized expression takes on the same type as the unparenthesized expression, C.99 §6.5.1 ¶5:
A parenthesized expression is a primary expression. Its type and value are identical to those of the unparenthesized expression. It is an lvalue, a function designator, or a void expression if the unparenthesized expression is, respectively, an lvalue, a function designator, or a void expression.
However, while a string literal is an expression, the converse is not true. Specifically, a string literal in of itself is not a type, but a defined entity. The initialization of arrays makes a specific allowance for a string literal, C.99 §6.7.8 ¶14:
An array of character type may be initialized by a character string literal, optionally enclosed in braces.
The other allowed initializers for an array are described in C.99 §6.7.8 ¶16:
Otherwise, the initializer for an object that has aggregate or union type shall be a brace enclosed list of initializers for the elements or named members.
A parenthesized expression is not a string literal, nor a brace enclosed list of initializers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With