LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   C Language Question (https://www.linuxquestions.org/questions/programming-9/c-language-question-916418/)

minivy 11-30-2011 01:17 PM

C Language Question
 
Hi Linux fans,

I am reusing the header file xhci.h in the link below and I have trouble to understand the line of code below.

Link:
http://git.kernel.org/?p=linux/kerne...7e6e08b3b46f5e

Line of code:
unsigned sw_lpm_support:1;

Question1: Why no base type in the code like int, short int, char, etc ?

Question2: What does the character ":1" do?

Thanks in advance

MrCode 11-30-2011 01:25 PM

I'm not so sure about Q2, but as to Q1: if there's no explicit type given in addition to the signed/unsigned qualifier, int is assumed, i.e. "unsigned" == "unsigned int".

…hope this helps. ;)

Tinkster 11-30-2011 02:53 PM

Moved: This thread is more suitable in <PROGRAMMING> and has been moved accordingly to help your thread/question get the exposure it deserves.

Cedrik 11-30-2011 03:36 PM

Q1 & Q2 it is an unsigned bit field, value can be 0 or 1

johnsfine 11-30-2011 04:19 PM

Q1 already answered perfectly by MrCode.

Q2: It is important that the line you quoted is inside a struct definition and that the following line is:

Code:

        unsigned                hw_lpm_support:1;
Alone and outside a struct definition, the line you asked about might just declare a one bit field as Cedrik said.

Inside a struct definition (which is where such syntax is most commonly used) it should allocate an entire unsigned int but allow that unsigned int to be shared with following bit fields.

So the immediately following hw_lpm_support in the linked code is another bit of the same unsigned int allocated by the declaration of sw_lpm_support.

Edit: I just wrote and tested a program I hoped would clarify the rules I described above. But either I misunderstood the rules myself or something is strange about my gcc.
Code:

#include <stdio.h>
typedef struct { unsigned x:1; unsigned y:1; char z; } a;
typedef struct { unsigned char x:1; unsigned char y:1; char z; } b;
int main(int argc, char *argv[])
{
    printf("sizeof(a)=%d\n", sizeof(a));
    printf("sizeof(b)=%d\n", sizeof(b));
    return 0;
}

The size of b is simple: x and y each use 1 bit of the same char, z is another char, so the total is 2.

I thought a would be 8. x and y each use 1 bit of the same unsigned int, z is an additional char, forcing three more chars for alignment. But actually sizeof(a) was 4, meaning that x forced a full unsigned int into the struct as I expected, but both y and z then used left over bits of that unsigned int. (I don't use this stuff in real work).

dwhitney67 11-30-2011 06:56 PM

Quote:

Originally Posted by johnsfine (Post 4538601)
I thought a would be 8. x and y each use 1 bit of the same unsigned int, z is an additional char, forcing three more chars for alignment. But actually sizeof(a) was 4, meaning that x forced a full unsigned int into the struct as I expected, but both y and z then used left over bits of that unsigned int. (I don't use this stuff in real work).

On my 64-bit system, using GCC 4.5.2, I received the following warnings when I compiled with the -pedantic compiler option:
Code:

foo.c:3:16: warning: type of bit-field ‘x’ is a GCC extension
foo.c:3:16: warning: type of bit-field ‘y’ is a GCC extension

When I ran the executable, I obtained these results:
Code:

sizeof(a)=4
sizeof(b)=2

I presume this is what you originally anticipated would be the result for 'a'.

P.S. On a 64-bit system, sizeof() returns a long int, thus I had to modify the formatting operator in the printf()s to be "%ld".

--------------------

EDIT: I just re-read your post; it seems I misread it. You anticipated the size of 'a' would be 8, and instead yielded 4... just like I did on my system.

koyi 12-02-2011 09:14 AM

Some reference on Wikipedia, if it helps.

http://en.wikipedia.org/wiki/C_syntax#Bit_fields


All times are GMT -5. The time now is 02:22 PM.