C++, неявное усечение от 'int' до битового поля
Я хочу создать 64-битную структуру данных, в которой каждый бит должен содержать значение. для этого я создал структуру следующим образом. (на всякий случай это связано с протоколом J1939 и именем ControlApplication NAME)
typedef struct CA_NAME {
unsigned IdentityNumber : 21; // 21 bits Byte 1.1 to 3.5
unsigned ManufactorerCode : 11; // 11 bits Byte 3.6 to 4.8
unsigned ECUInstance : 3; // 3 bits Byte 5.1 to 5.3
unsigned functionInstance : 5; // 5 bits Byte 5.4 to 5.8
unsigned Function : 8; // 8 bits Byte 6
unsigned Reserved : 1; // 1 bit Byte 7.1
unsigned VehicleSystem : 7; // 7 bits Byte 7.2 to 7.8
unsigned VehicleSystemInstance : 4; // 4 bits Byte 8.1 to 8.4
unsigned IndustryGroup : 3; // 3 bits Byte 8.5 to 8.7
unsigned ArbitraryAddressCapable : 1; // 1 bit Byte 8.8
} CA_NAME; /*64Bit NAME*/
Теперь я хочу инициализировать экземпляр объекта CA_NAME
CA_NAME j1939 = {};
void Create_CA_NAME() {
j1939.IdentityNumber = 0xFE0D32;
j1939.ManufactorerCode = 0x57;
....
}
Здесь я получаю ошибку анализа в реальном времени (я думаю, из ReSharper), что (то есть для первого назначения)
Как правильно инициализировать экземпляр структуры?
1 ответ
Постоянная 0xFE0D32
имеет 24 значения бит (и действительно имеет тип int
).
Вы пытаетесь инициализировать 21-разрядное битовое поле без знака IdentityNumber
с константой, которая превышает его диапазон. Компилятор достаточно любезен, чтобы предупредить вас об этой потенциальной ошибке.
Кроме того, вы компилируете как C++, что объясняет, почему:
CA_NAME j1939 = {};
не генерирует ошибку в C++, но будет в C. На самом деле вам не нужен инициализатор, так какj1939
это глобальная переменная. Если вы настаиваете на явном инициализаторе, либо укажите фактические значения, либо просто напишитеCA_NAME j1939 = { 0 };
- Сообщение об ошибке заумно, давая вам почувствовать ужасную сложность C++.