C variable width bitfield

c, gcc, struct

Solution

You can not define the size of a bit-field at run-time in C. But you don't need a bit-field to print binary values, simply write a function to print a number in binary format, like the one here: Is there a printf converter to print in binary format?

Then write a simple loop to print your numbers:

//get n
for (int i = 0; i < n; i++) {
    print_binary(i);
}

Edit: To answer your question about printing negative numbers coded in two's complement which don't have native types in C (like int8_t, int16_t, int32_t..), like you found out for a signed word coded on N bits in 2's complement, for negative numbers you can use the equality:

Xnegative = 2^N - Xpositive

//get n
for (uint32_t Xpos = 0; Xpos < (1<<n); Xpos++) {
    if (Xpos > 1<<(n-1))
        printf("%d\n", -(1 << n) + Xpos);
    else
        printf("%u\n", Xpos);
}

Problem

I don't ask a lot of questions here, so forgive me if my "question asking skills" are a bit rusty. Here goes: I've looked around, and can't seem to find a solution to this. The idea is that the program prints out a table of the decimal (signed and unsigned), hexadecimal, and binary representations of each possible value of a number with an arbitrary bit size. It accepts the bit size from argv, and an example output should be (focusing on the binary representations): ``` $ ./test 2 00 01 10 11 $ ./test 4 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 ``` This works fine if I use a preprocessor macro, but that means I have to re-compile every time I want to change the bit size. Argv would solve all my problems, if it weren't for one small caveat. And that is that the compiler doesn't like what I'm trying to do, even though it seems perfectly logical. What I'm trying to do is this: ``` int bit_size = atoi(argv[1]); struct { unsigned int a : bit_size; } test; ``` But the compiler gives me an error, quite sternly telling me I can't do that ("bitfield not an integer constant"). Okay...so I try using a `const int` instead: ``` const int bit_size = atoi(argv[1]); struct { unsigned int a : bit_size; } test; ``` I get the same exact error. Just to note: what GCC wants me to do is this: ``` struct { unsigned int a : 8; } test; ``` And it works without any problem. But I need to be able to vary that. I am perplexed. Note that I do not want or need the bitfield's width to be able to change mid-program, which is what I'm assuming GCC's trying to prevent me from doing. This is effectively a one-shot operation. Also note that I'm not trying to do this on a normal variable like this question (and many others like it). This question also has nothing to do with what I'm trying to accomplish. Also, if it helps, this is an example of what displays when it runs without error (bitfield width = 4): ``` $ ./test 4 $ cat table.md Table for a/an 4-bit integer: | Unsigned | Signed | Hex | Binary | Sign Bit | |:--------:|:------:|:---:|:------:|:--------:| | 0 | 0 | 0 | 0000 | 0 | | 1 | 1 | 1 | 0001 | 0 | | 2 | 2 | 2 | 0010 | 0 | | 3 | 3 | 3 | 0011 | 0 | | 4 | 4 | 4 | 0100 | 0 | | 5 | 5 | 5 | 0101 | 0 | | 6 | 6 | 6 | 0110 | 0 | | 7 | 7 | 7 | 0111 | 0 | | 8 | -8 | 8 | 1000 | 1 | | 9 | -7 | 9 | 1001 | 1 | | 10 | -6 | A | 1010 | 1 | | 11 | -5 | B | 1011 | 1 | | 12 | -4 | C | 1100 | 1 | | 13 | -3 | D | 1101 | 1 | | 14 | -2 | E | 1110 | 1 | | 15 | -1 | F | 1111 | 1 | ```

Original source

Related problems