Is there a way to change this C ++ structure assignment block to work in direct C

The following code is in the device, which gives the identifier deviceId (LXdeviceInfo) when enumerated through the IrDA socket connection. This is important only to explain why I would like to keep the data types as similar as possible, but be able to compile with ansi C

With # includes of windows.h and af_irda.h, the following code compiles without errors in the C ++ compiler, but breaks into the C compiler just below the structure assignment (see ERROR here). Ideally, I would like to initialize the identifier of the structure element as an array of characters, keeping it the same as in the source code, so I can check the value of LXdeviceInfo in the same way as when I would request it from a device call from the PC connector.

Is there a way to change this assignment block to work in direct 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. } 
+6
source share
2 answers

Remove the parentheses around the string literal. The brackets turn the macro into an expression that will decompose into a pointer type, which makes it not compiled in your C compiler. The initialization type cannot be used to initialize an array. Without parentheses, a string literal is used to initialize the array.

 #define PROD_FAMILY_NAME "product name goes here" 

The C standard states that the expression in parentheses is of the same type as the unexpressed expression, C.99 & sect; 6.5.1? 5:

The expression in parentheses is the main expression. Its type and meaning are identical to type and uneven expression. This value is an lvalue, a function designation, or a void expression, if the non-common expression is, respectively, an lvalue, a function designation or void.

However, although a string literal is an expression, the converse is not true. In particular, a string literal itself is not a type, but a specific object. The initialization of arrays gives a specific value for the string literal, C.99 & sect; 6.7.8 and para; fourteen:

A character type array can be initialized with a character string literal , optionally enclosed in braces.

Other valid initializers for the array are described in C.99, section 6.7.8 and para.16:

Otherwise, the initializer for an object that is of type aggregate or union must be a closed list of initializers for elements or named members.

The expression in parentheses is not a string literal, nor is it a copied list of initializers.

+11
source

Since PROD_FAMILY_NAME is a string (constant), the compiler expects the ID be declared as something like uint8_t *ID; since strings are usually represented as pointers to characters in memory in C. See my example here: http://ideone.com/m5ZZl0

To do this using an array of characters, as you have, you need to do strcpy or memcpy on behalf of the product family to your byte array of ID , since C does not support direct array assignment until I know. If the product name is variable, but does not change and does not go beyond, I would recommend using a uint8_t* -typed ID , but if you need a copy of the name and don’t want to dynamically allocate memory that you may want to stick to the array (but note that older version of the C standard does not support non-static length arrays, but [there are ways to get around this by using peremennoy- length of the array at the end of the structure, but you often have to manually keep track of the size of the structure in such cases when sizeof() returns 0 for such weight Willow, but things like strlen() , still work fine.)


I seem to have forgotten about this, while array assignment is not allowed, something else like char array[] = "literal string"; . ( http://ideone.com/vilDOa vs. http://ideone.com/gEC2k2 ) So mine above was a bit pointless, but I think that dynamically dimensional structures are not so good in the idea if you want to have an array of such structures , in which case the char* method might be a better idea (even if it's just a pointer to an array elsewhere).

0
source

Source: https://habr.com/ru/post/951670/


All Articles