0

I am trying to make a struct that could hold 208 bytes bits. My intentions are using every 3 bits of variables to store 68 values each between 0 and 4.

I currently have this, but am getting quite a few errors:

typedef struct {
    uint64_t _1vr = 0;
    uint64_t _2vr = 0;
    uint64_t _3vr = 0;
    uint16_t _4vr = 0;
} TEST;

const TEST test_bits = {
    ._1vr = (BVUS_ZAC1 << 0) | (BVUS_ZAC2 << 3) | (BVUS_VISOKO << 6) | (BVUS_NIZKO2 << 9) | (BVUS_VISOKO << 12) |
    (BVUS_NIZKO1 << 15) | (BVUS_VISOKO << 18) | (BVUS_NIZKO1 << 21) | (BVUS_VISOKO << 24) | (BVUS_NIZKO1 << 27) |
    (BVUS_VISOKO << 30) | (BVUS_NIZKO1 << 33) | (BVUS_VISOKO << 36) | (BVUS_NIZKO1 << 39) | (BVUS_VISOKO << 42) |
    (BVUS_NIZKO1 << 45) | (BVUS_VISOKO << 48) | (BVUS_NIZKO1 << 51) | (BVUS_VISOKO << 54) | (BVUS_NIZKO1 << 57) |
    (BVUS_VISOKO << 60),
    ._2vr = (BVUS_NIZKO2 << 0) | (BVUS_VISOKO << 3) | (BVUS_NIZKO2 << 6) | (BVUS_VISOKO << 9) | (BVUS_NIZKO2 << 12) |
    (BVUS_VISOKO << 15) | (BVUS_NIZKO2 << 18) | (BVUS_VISOKO << 21) | (BVUS_NIZKO2 << 24) | (BVUS_VISOKO << 27) |
    (BVUS_NIZKO2 << 30) | (BVUS_VISOKO << 33) | (BVUS_NIZKO2 << 36) | (BVUS_VISOKO << 39) | (BVUS_NIZKO1 << 42) |
    (BVUS_VISOKO << 45) | (BVUS_NIZKO1 << 48) | (BVUS_VISOKO << 51) | (BVUS_NIZKO1 << 54) | (BVUS_VISOKO << 57) |
    (BVUS_NIZKO1 << 60),
    ._3vr = (BVUS_VISOKO << 0) | (BVUS_NIZKO1 << 3) | (BVUS_VISOKO << 6) | (BVUS_NIZKO1 << 9) | (BVUS_VISOKO << 12) |
    (BVUS_NIZKO1 << 15) | (BVUS_VISOKO << 18) | (BVUS_NIZKO1 << 21) | (BVUS_VISOKO << 24) | (BVUS_NIZKO2 << 27) |
    (BVUS_VISOKO << 30) | (BVUS_NIZKO2 << 33) | (BVUS_VISOKO << 36) | (BVUS_NIZKO2 << 39) | (BVUS_VISOKO << 42) |
    (BVUS_NIZKO2 << 45) | (BVUS_VISOKO << 48) | (BVUS_NIZKO2 << 51) | (BVUS_VISOKO << 54) | (BVUS_NIZKO2 << 57) |
    (BVUS_VISOKO << 60),
    ._4vr = (BVUS_NIZKO2 << 0) | (BVUS_VISOKO << 3) | (BVUS_NIZKO2 << 6) |     (BVUS_VISOKO << 9) | (BVUS_NIZKO1 << 12)
};
  • 4x: Warning 19 (near initialization for 'test_bits') [enabled by default]
  • 4x: Warning 4 excess elements in struct initializer [enabled by default]
  • Error 1 expected ':', ',', ';', '}' or '__attribute__' before '=' token
  • Whole bunch of: Warning 51 left shift count >= width of type [enabled by default]
  • Error 2 unknown field '_1vr' specified in initializer
  • Error 20 unknown field '_2vr' specified in initializer
  • Error 38 unknown field '_3vr' specified in initializer
  • Error 56 unknown field '_4vr' specified in initializer

These variables are defined in global scope.

I have no clue whats going on. To be honest I dont see anything wrong (of course I am wrong but...)

EDIT:

Doing exactly what WChargin said I still cant get rid of next errors:

  • Error 12 (near initialization for 'test_bits._1vr')
  • Error 24 (near initialization for 'test_bits._2vr')
  • Error 36 (near initialization for 'test_bits._3vr')
  • Error 11 initializer element is not constant
  • Warning 1 left shift count >= width of type [enabled by default]

EDIT2:

I am doing this on a 8-bit architecture.

mctylr
  • 5,159
  • 20
  • 32
user1806687
  • 934
  • 1
  • 10
  • 27

2 Answers2

1

The problems:

  • You can't initialize struct members in your struct declaration. That is, your uint64_t _1vr = 0; statements are invalid. That's why you get the "expected…before '=' token" error.
  • Presumably, your constants are defined as the wrong size—are they not long enough? I've just used #defines here for simplicity, and it works.

This compiles fine (with gcc -c):

#include <stdint.h>

typedef struct {
    uint64_t _1vr;
    uint64_t _2vr;
    uint64_t _3vr;
    uint16_t _4vr;
} TEST;

#define BVUS_ZAC1    0ul
#define BVUS_ZAC2    0ul
#define BVUS_VISOKO  0ul
#define BVUS_NIZKO1  0ul
#define BVUS_NIZKO2  0ul

const TEST test_bits = {
    ._1vr = (BVUS_ZAC1 << 0) | (BVUS_ZAC2 << 3) | (BVUS_VISOKO << 6) | (BVUS_NIZKO2 << 9) | (BVUS_VISOKO << 12) |
    (BVUS_NIZKO1 << 15) | (BVUS_VISOKO << 18) | (BVUS_NIZKO1 << 21) | (BVUS_VISOKO << 24) | (BVUS_NIZKO1 << 27) |
    (BVUS_VISOKO << 30) | (BVUS_NIZKO1 << 33) | (BVUS_VISOKO << 36) | (BVUS_NIZKO1 << 39) | (BVUS_VISOKO << 42) |
    (BVUS_NIZKO1 << 45) | (BVUS_VISOKO << 48) | (BVUS_NIZKO1 << 51) | (BVUS_VISOKO << 54) | (BVUS_NIZKO1 << 57) |
    (BVUS_VISOKO << 60),
    ._2vr = (BVUS_NIZKO2 << 0) | (BVUS_VISOKO << 3) | (BVUS_NIZKO2 << 6) | (BVUS_VISOKO << 9) | (BVUS_NIZKO2 << 12) |
    (BVUS_VISOKO << 15) | (BVUS_NIZKO2 << 18) | (BVUS_VISOKO << 21) | (BVUS_NIZKO2 << 24) | (BVUS_VISOKO << 27) |
    (BVUS_NIZKO2 << 30) | (BVUS_VISOKO << 33) | (BVUS_NIZKO2 << 36) | (BVUS_VISOKO << 39) | (BVUS_NIZKO1 << 42) |
    (BVUS_VISOKO << 45) | (BVUS_NIZKO1 << 48) | (BVUS_VISOKO << 51) | (BVUS_NIZKO1 << 54) | (BVUS_VISOKO << 57) |
    (BVUS_NIZKO1 << 60),
    ._3vr = (BVUS_VISOKO << 0) | (BVUS_NIZKO1 << 3) | (BVUS_VISOKO << 6) | (BVUS_NIZKO1 << 9) | (BVUS_VISOKO << 12) |
    (BVUS_NIZKO1 << 15) | (BVUS_VISOKO << 18) | (BVUS_NIZKO1 << 21) | (BVUS_VISOKO << 24) | (BVUS_NIZKO2 << 27) |
    (BVUS_VISOKO << 30) | (BVUS_NIZKO2 << 33) | (BVUS_VISOKO << 36) | (BVUS_NIZKO2 << 39) | (BVUS_VISOKO << 42) |
    (BVUS_NIZKO2 << 45) | (BVUS_VISOKO << 48) | (BVUS_NIZKO2 << 51) | (BVUS_VISOKO << 54) | (BVUS_NIZKO2 << 57) |
    (BVUS_VISOKO << 60),
    ._4vr = (BVUS_NIZKO2 << 0) | (BVUS_VISOKO << 3) | (BVUS_NIZKO2 << 6) |     (BVUS_VISOKO << 9) | (BVUS_NIZKO1 << 12)
};

Note, however, that sizeof(TEST) yields 32 on my (64-bit) machine. This may not be what you want.

wchargin
  • 15,589
  • 12
  • 71
  • 110
  • Constants are declared in enum. How can I ensure they are long enough? – user1806687 Jan 19 '15 at 20:15
  • @user1806687 See [this post](http://stackoverflow.com/a/366026/732016). Don't define them in an `enum`, I guess. – wchargin Jan 19 '15 at 20:16
  • sizeof(TEST) == 32!?? wtf? – Peter - Reinstate Monica Jan 19 '15 at 21:04
  • @PeterSchneider I am guessing uint16_t gets changed to uint64_t because he's on a 64bit machine. – user1806687 Jan 19 '15 at 21:25
  • Not changed, padded or aligned. – mctylr Jan 19 '15 at 22:09
  • Oh, I was parsing it as 32 bits, not bytes; it was late. 32 bytes is just 4*8 bytes, due to padding of the struct to a 8 byte border which is the natural alignment for a 64 bit machine. The size of the last member is not changed at all, the padding isn't used for anything. One can usually avoid that padding with some `pragma pack` or compiler option. That may be necessary in order to be space efficient or in order to match a hardware layout. – Peter - Reinstate Monica Jan 20 '15 at 06:14
0

On this particular architecture 64bits are defines as long long, so changing the defines @WChargin posted to ULL works.

user1806687
  • 934
  • 1
  • 10
  • 27
  • 1
    Any special reason why you don't use uint64_t instead of some implementation defined integer type if you want 64 bits? – Peter - Reinstate Monica Jan 19 '15 at 21:16
  • @PeterSchneider I am not getting what you're saying. – user1806687 Jan 19 '15 at 21:26
  • 2
    Instead of `#define BVUS_ZAC1 0uul` write `#define BVUS_ZAC1 ((uint64_t)0)`. That should make it obvious and implementation-independent how many bits the type of the literal has, and should fail to compile in case there is no 64 bit type (not sure whether the standard mandates one). – Peter - Reinstate Monica Jan 20 '15 at 06:08
  • Or, even better, just make it an actual `uint64_t` variable—the `#define`s in my example were just so the code would compile. – wchargin Jan 20 '15 at 15:01