I am currently using "ANSI-C/cC++ Compiler for HC12 V-5.0.40 Build 10020, Jan 21 2010".
In my code, I am using this macro:
Mk4Bytes(x) { (((u8)((x) >> 24)) , ((u8)((x) >> 16)) , ((u8)((x) >> 8)) , ((u8)(x))) }
which I have used successfully in other compilers. However, when I used it to initialize a field in a structure, I got the error "ERROR C2207: Initializer must be constant"
Here is a excerpt of my code:
typedef unsigned char u8;
typedef struct {
u8 partnumber[4];
u8 version[2];
} tIDheader;
#pragma CONST_SEG IDHEADER
const tIDheader IDheader = {
Mk4Bytes(12345678),
"A0"
};
While I know that I could simply change the field definition to use "unsigned long" instead of an array of bytes, the struct is actually defined in automatically generated code, so I am not allowed to change the definition.
Anyway, the value given to the macro is a constant so the resulting expression is a constant expression, so I would expect the compiler to replace the expression with { 0x00, 0xBC, 0x61, 0x4E }, which is a constant initializer.
As I said, I have used this macro successfully with other compilers. Is this a bug with this compiler?
已解决! 转到解答。
The provided macro contains one pair of braces too much .
Try:
#define Mk4Bytes(x) { ((u8)((x) >> 24)) , ((u8)((x) >> 16)) , ((u8)((x) >> 8)) , ((u8)(x)) }
The original code contained an expression like this:
char buf[1] = {(1,2)};
using (1,2) can be taken by some compilers as comma expression with a value of 2. But it is obviously not what was intended, I don't think the comma operator is legal in a constant expression in C, I did not look it up though. In C++ the code would be legal (well legal, but still not do what was intended ...).
Daniel
A more readable version would be:
#define x 12345678 #define x0 ((u8)(x >> 24)) #define x1 ((u8)(x >> 16)) #define x2 ((u8)(x >> 8)) #define x3 ((u8)(x )) const tIDheader IDheader = { {x0, x1, x2, x3}, {'A','0'} };
Hello,
Even though either style of macro solution gives the intended outcome, I notice that a couple of C2705 compiler warning messages are generated with with either approach. This is for "Possible loss of data", which in this case is not of any consequence. However, attempts to eliminate the warning (other than globally inhibiting them) have failed.
Lundin wrote:
#define x 12345678 #define x0 ((u8)(x >> 24)) #define x1 ((u8)(x >> 16)) #define x2 ((u8)(x >> 8)) #define x3 ((u8)(x )) const tIDheader IDheader = { {x0, x1, x2, x3}, {'A','0'} };
Using Lundin's approach, I can identify that a warning is associated with each of the x2 and x3 macros, but not the x0 and x1 macros. The x value is obviously a 32 bit quantity, so there is no ambiguity here.
I am curious as to the cause of the warnings.
Regards,
Mac
Hello,
Another issue, not connected with the macro, but with the structure initialisation, is that the null termination byte associated with the string has not been allowed for within the second structure element. This results in a compiler warning, but the expected result occurs. To avoid this warning, perhaps the following should be used.
const tIDheader IDheader = {
Mk4Bytes(12345678),
{'A','0'}
};
Regards,
Mac
The provided macro contains one pair of braces too much .
Try:
#define Mk4Bytes(x) { ((u8)((x) >> 24)) , ((u8)((x) >> 16)) , ((u8)((x) >> 8)) , ((u8)(x)) }
The original code contained an expression like this:
char buf[1] = {(1,2)};
using (1,2) can be taken by some compilers as comma expression with a value of 2. But it is obviously not what was intended, I don't think the comma operator is legal in a constant expression in C, I did not look it up though. In C++ the code would be legal (well legal, but still not do what was intended ...).
Daniel