I have the following statement
CAN0_CTL_R &= ~ CAN_CTL_INIT;
and the required misra warning:
If the bitwise operators ~ and << are applied to an operand of underlying type unsigned char or unsigned short, the result shall be immediately cast to the underlying type of the operand
the registers is defined as the following:
#define CAN_CTL_INIT 0x00000001U // Initialization
#define CAN0_CTL_R (*((volatile uint32_t *)0x40040000U))
since there is no short or char datatype, what is causing the warning?
As far as I can tell the warning does not apply to the statement you present, given the macro definitions you say apply. I speculate, however, that it is related to the integer constant 0x00000001U. Interpreted as an integer constant, that has type unsigned int, but it is possible that the MISRA tool misinterprets it as having a narrower type because its value would fit in a narrower one.
I suggest reducing the likelihood of machine or human misinterpretation by specifying the type explicitly:
#define CAN_CTL_INIT ((unsigned int) 0x00000001U) // Initialization
or
#define CAN_CTL_INIT ((uint32_t) 0x00000001U) // Initialization
. The former yields an expression of the same type and value as the original on every conforming C implementation. The latter is probably equivalent for you, and you may prefer it stylistically. (And if the latter happens not to be equivalent for you, then you should consider whether it's actually what you wanted.)
Sorting through a retired engineers code and I encountered a fairly simple macro, but my C knowledge isn't great.
#define mem32(addr) (*(unsigned long volatile *)(addr))
Am I correctly calling this a type casting pointer dereference?
It types casts addr and then derefences it? Or the other way around? Does it matter?
Does order matter for type qualifiers and type specifiers? I had assumed (before this) type qualifiers had to precede type specifiers, but that must not be the case
Syntax question. What's the purpose of the 2nd * ?
Am I correctly calling this a type casting pointer dereference?
Yes.
It types casts addr and then derefences it? Or the other way around? Does it matter?
The *(unsigned long volatile *)(addr) is typecasting addr and then dereferencing it.
Does order matter for type qualifiers and type specifiers?
No. Order doesn't matter. C11 section ยง6.7.2/2
[...] the type specifiers may occur in any order, possibly
intermixed with the other declaration specifiers. [...]
The cast (unsigned long volatile *)(addr) happens before the dereferencing.
And no, the order of the words unsigned, long, and volatile does not matter as long as no further operators are mixed in. I. e. volatile int* and int volatile* are the same, but int * volatile is something different.
On a high level, the purpose of this macro is to take any pointer, and read the first four bytes from that memory address.
However, this invokes undefined behavior if the pointer that's passed to mem32 is neither a pointer to long or char! This is due to strict aliasing rules. Older compilers used to safely generate the intended code for this macro, but modern compilers may just optimize the code using that macro away if they prove a type mismatch. So, don't use this in new code.
#define PORTC *(unsigned char volatile *)(0x1003)
#define DDRC *(unsigned char volatile *)(0x1007)
So I've been trying to read some stuff about embedded C. Initially I thought this macro was a pointer-to-pointer type but then I soon assumed the last star is actually a dereference rather than a type-cast, am I correct? Dereferencing to the location 0x1003/0x1007.
It is used like: PORTC = <some hex value>
Question is what makes this different from a pointer type-cast? Is there some sort of 'provision' in the C specifications? Or am I just an idiot...
Also I don't quite know how to phrase this and so I couldn't do a quick search first...
It's just the way the C grammar is defined.
To be a cast, the expression needs parenthesis: (type)sub-expression casts sub-expression to type type.
Your example, *(unsigned char volatile *)(0x1003) is composed of 2 sub-expressions:
a "lonely" star: *
a cast: (unsigned char volatile *)(0x1003)
The cast is composed of the type inside () and a value.
So, the whole expression is interpreted as a pointer, then de-referenced to set the memory area pointed to.
No, it is quite a cast.
First, the memory location (as integer) is cast into an appropriate pointer which is then dereferenced.
That code is basically equivalent to: Put <some hex value> in the memory at the address (0x1003) (or whatever the value is). In some embedded devices (and not only) ports are mapped at memory locations.
The cast instructs the compiler that the memory addresses 0x1003 and 0x1007 are to be treated as unsigned char volatile * pointers, and the * dereferencing operator acts on that pointer to fetch the pointed-to value, which in this case is 1 byte.
Applying the unary * makes this expression a valid lvalue (it wouldn't be so without it) which means that it is something you can assign to.
I'm a tad confused between what is and is not a Constant Expression in C, even after much Googleing. Could you provide an example of something which is, and which is not, a Constant Expression in C?
A constant expression can be evaluated at compile time. That means it has no variables in it. For example:
5 + 7 / 3
is a constant expression. Something like:
5 + someNumber / 3
is not, assuming someNumber is a variable (ie, not itself a compile-time constant).
There is another subtlety to constant expressions. There are some things that are known to the compiler, but cannot be known to the preprocessor.
For example (24*60*60) can be computed by both, but sizeof struct foo is only known to the compiler. This distinction can matter if you are trying to verify that a struct is defined to meet an externally mandated size, or that its members are mapped at externally specified offsets. (This use case often arises when coding device drivers where the struct describes device registers as layed out in memory space.)
In that instance you cannot simply say #if (sizeof(struct UART) == 12) because the preprocessor operates at a pass ahead of the compilation and simply cannot know the size of any types. It is, however, a constant expression and would be valid as an initializer for a global variable (e.g. int UARTwords = sizeof(struct UART) / sizeof(short);), or to declare the size of an array (e.g. unsigned char UARTmirror[sizeof(struct UART)];)
Nobody seems have mentioned yet another kind of constant expression: address constants. The address of an object with static storage duration is an address constant, hence you can do this kind of thing at file scope:
char x;
char *p = &x;
String literals define arrays with static storage duration, so this rule is also why you can do this at file scope:
char *s = "foobar";
Any single-valued literal is a constant expression.
3 0.0f '\n'
(String literals are weird, because they're actually arrays. Seems "hello" isn't really a constant, as it ends up having to be linked and all that, and the address and contents can change at runtime.)
Most operators (sizeof, casts, etc) applied to constants or types are constant expressions.
sizeof(char)
(byte) 15
Any expression involving only constant expressions is itself also a constant expression.
15 + 3
0.0f + 0.0f
sizeof(char)
Any expression involving function calls or non-constant expressions is usually not a constant expression.
strlen("hello")
fifteen + x
Any macro's status as a constant expression depends on what it expands to.
/* Always a constant */
#define FIFTEEN 15
/* Only constant if (x) is
#define htons(x) (( ((x) >> 8) | ((x) << 8) ) & 0xffff)
/* Never constant */
#define X_LENGTH strlen(x)
I originally had some stuff in here about const identifiers, but i tested that and apparently it doesn't apply in C. const, oddly enough, doesn't declare constants (at least, not ones "constant" enough to be used in switch statements). In C++, however, it does.
Another fun little wrinkle: in C, the value of an 'enum' is a constant, but may only be used after the declaration of the 'enum' is complete. The following, for example, is not acceptable in standard C, though it is acceptable in C++:
enum {foo=19, bar, boz=bar+5;};
It could be rewritten:
enum {foo=19, bar}; enum {boz=bar+5;};
though this would end up defining multiple different enumeration types, rather than one which holds all the values.
Also integral character constants as 'a' or '\n' are constants that the compiler recognizes as such. They have type int.
struct foo { unsigned x:1; } f;
printf("%d\n", (int)sizeof(f.x = 1));
What is the expected output and why? Taking the size of a bitfield lvalue directly isn't allowed. But by using the assignment operator, it seems we can still take the size of a bitfield type.
What is the "size of a bitfield in bytes"? Is it the size of the storage unit holding the bitfield? Is it the number of bits taken up by the bf rounded up to the nearest byte count?
Or is the construct undefined behavior because there is nothing in the standard that answers the above questions? Multiple compilers on the same platform are giving me inconsistent results.
You are right, integer promotions aren't applied to the operand of sizeof:
The integer promotions are applied only: as part of the usual arithmetic conversions, to certain argument expressions, to the operands of the unary +, -, and ~ operators, and to both operands of the shift operators, as specified by their respective subclauses.
The real question is whether bitfields have their own types.
Joseph Myers told me:
The conclusion
from C90 DRs was that bit-fields have their own types, and from C99 DRs
was to leave whether they have their own types implementation-defined, and
GCC follows the C90 DRs and so the assignment has type int:1 and is not
promoted as an operand of sizeof.
This was discussed in Defect Report #315.
To summarize: your code is legal but implementation-defined.
The C99 Standard (PDF of latest draft) says in section 6.5.3.4 about sizeof constraints:
The sizeof operator shall not be applied to an expression that has function type or an
incomplete type, to the parenthesized name of such a type, or to an expression that
designates a bit-field member.
This means that applying sizeof to an assignment expression is allowed.
6.5.16.3 says:
The type of an assignment expression is the type of the left operand ...
6.3.1.1.2 says regarding integer promotions:
The following may be used in an expression wherever an int or unsigned int may be used:
...
A bit-field of type _Bool, int, signed int, or unsigned int.
If an int can represent all values of the original type,
the value is converted to an int;
otherwise, it is converted to an unsigned int.
So, your test program should output the size of an int, i.e.,
sizeof(int).
Is there any compiler that does not to this?
Trying to get the size of a bitfield isn't legal, as you have seen. (sizeof returns the size in bytes, which wouldn't make much sense for a bitfield.)
sizeof(f.x = 1) will return the size of the type of the expression. Since C doesn't have a real "bitfield type", the expression (here: an assignment expression) usually gets the type of the bit field's base type, in your example unsigned int, but it is possible for a compiler to use a smaller type internally (in this case probably unsigned char because it's big enough for one bit).
sizeof( f.x = 1)
returns 1 as its answer. The sizeof(1) is presumably the size of an integer on the platform you are compiling on, probably either 4 or 8 bytes.
No, you must be thinking of the == operator, which yields a "boolean" expression of type int in C and indeed bool in C++.
I think the expression will convert the value 1 to the correspondin bitfield type and assign it to the bitfield. The result should also be a bitfield type because there are no hidden promotions or conversions that I can see.
Thus we are effectively getting access to the bitfield type.
No compiler diagnostic is required because "f.x = 1" isn't an lvalue, i.e. it does not designate the bitfield directly. It's just a value of type "unsigned :1".
I'm specifically using "f.x = 1" because "sizeof f.x" takes the size of a bitfield lvalue, which is clearly not allowed.
The sizeof(1) is presumably the size of an integer on the platform you are compiling on, probably either 4 or 8 bytes.
Note that I'm NOT taking sizeof(1), which is effectively sizeof(int). Look close, I'm taking sizeof(f.x = 1), which should effectively be sizeof(bitfield_type).
I'd like to see a reference to something that tells me whether the construct is legal. As an added bonus, it would be nice if it told me what sort of result is expected.
gcc certainly disagrees with the assertion that sizeof(bitfield_type) should be the same as sizeof(int), but only on some platforms.
Trying to get the size of a bitfield isn't legal, as you have seen. (sizeof returns the size in bytes, which wouldn't make much sense for a bitfield.)
So are you stating that the behavior is undefined, i.e. it has the same degree of legality as "*(int *)0 = 0;", and compilers can choose to fail to handle this sensibly?
That's what I'm trying to find out. Do you assume that it's undefined by omission, or is there something that explicitly declares it as illegal?
The
(f.x = 1)
is not an expression, it is an assignment and thus returns the assigned value. In this case, the size of that value depends on the variable, it has been assigned to.
unsigned x:1
has 1 Bit and its sizeof returns 1 byte (8 bit alignment)
If you would use
unsigned x:12
then the sizeof(f.x = 1) would return 2 byte (again because of the 8 bit alignment)
is not an expression, it is an assignment and thus returns the assigned value. In this case, the size of that value depends on the variable, it has been assigned to.
First, it IS an expression containing the assignment operator.
Second, I'm quite aware of what's happening in my example :)
then the sizeof(f.x = 1) would return 2 byte (again because of the 8 bit alignment)
Where did you get this? Is this what happens on a particular compiler that you have tried, or are these semantics stated in the standard? Because I haven't found any such statements. I want to know whether the construct is guaranteed to work at all.
in this second example, if you would define your struct as a
struct foo { unsigned x:12} f;
and then write a value like 1 into f.x - it uses 2 Bytes because of the alignment. If you do an assignment like
f.x = 1;
and this returns the assigned value. This is quite similar to
int a, b, c;
a = b = c = 1;
where the asignment is evaluated from right to left. c = 1 assigns 1 to the variable c and this asignment returns the assigned value and assigns it to b (and so forth) until 1 is assigned to a
it is equal to
a = ( b = ( c = 1 ) )
in your case, the sizeof gets the size of your asignment, wich is NOT a bitfield, but the variable assigned to it.
sizeof ( f.x = 1)
does not return the bitfields size, but the variable assigment which is a 12 bit representation of the 1 (in my case) and therefore sizeof() returns 2 byte (because of the 8bit aligment)
Look, I understand full well what I'm doing with the assignment trick.
You are telling me that the size of a bitfield type is rounded up to the cloest byte count, which is one option I listed in the initial question. But you didn't back it up with references.
In particular, I have tried various compilers which give me sizeof(int) instead of sizeof(char) EVEN if I apply this to a bitfield with only has a single bit.
I wouldn't even mind if multiple compilers randomly get to choose their own interpretation of this construct. Certainly bitfield storage allocation is quite implementation-defined.
However, I really do want to know whether the construct is GUARANTEED to work and yield SOME value.
CL, I've seen your citations before, and agree they're totally relevant, but even after having read them I wasn't sure whether the code is defined.
6.3.1.1.2 says regarding integer promotions:
Yes, but integer promotion rules only apply if a promotion is in fact carried out. I do not think that my example requires a promotion. Likewise if you do
char ch;
sizeof ch;
... then ch also isn't promoted.
I think we are dealing directly with the bitfield type here.
I've also seen gcc output 1 while many other compilers (and even other gcc versions) don't. This doesn't convince me that the code is illegal because the size could just as well be implementation-defined enough to make the result inconsistent across multiple compilers.
However, I'm confused as to whether the code may be undefined because nothing in the standard seems to state how the sizeof bitfield case is handled.
Wouldn't
(f.x = 1)
be an expression evaluating to true (technically in evaluates to result of the assignment, which is 1/true in this case), and thus,
sizeof( f.x = 1)
is asking for the size of true in terms of how many chars it would take to store it?
I should also add that the Wikipedia article on sizeof is nice. In particular, they say "sizeof is a compile-time operator that returns the size, in multiples of the size of char, of the variable or parenthesized type-specifier that it precedes."
The article also explains that sizeof works on expressions.