C++ 神秘结构赋值与 int 截断
C++ Mystic structure assignment with int truncated
我有以下代码 (c++11) :
#include <iostream>
using namespace std;
//Icons
typedef struct
{
union
{
struct
{
uint8_t a : 1;
uint8_t b : 1;
uint8_t c : 1;
uint8_t : 5;
};
uint8_t Data;
} Bla;
union
{
struct
{
uint8_t d : 1;
uint8_t e : 1;
uint8_t : 6;
};
uint8_t Data;
} Foo;
union
{
struct
{
uint8_t f : 1;
uint8_t g : 1;
uint8_t h : 1;
uint8_t i : 1;
uint8_t : 4;
};
uint8_t Data;
} Bar;
}TypeStruct;
int main()
{
static constexpr TypeStruct NONE = {0x00,0,0};
static constexpr TypeStruct A = {0x01,0,0};
static constexpr TypeStruct B = {0x02,0,0};
static constexpr TypeStruct C = {0x04,0,0};
return 0;
}
在 IAR 上编译和工作正常,但在迂腐的 GCC 下,我收到以下错误,这困扰了我几天...
$g++ -std=c++11 -o main *.cpp
main.cpp: In function ‘int main()’:
main.cpp:50:52: warning: large integer implicitly truncated to unsigned type [-Woverflow]
static constexpr TypeStruct B = {0x02,0,0};
^
main.cpp:51:52: warning: large integer implicitly truncated to unsigned type [-Woverflow]
static constexpr TypeStruct C = {0x04,0,0};
^
我不明白为什么!
也许与 union 有关,但我尝试了不同的着作,但没有匹配:
{1,0,0} 或 {{1},{0},{0}} 或 {{1,0,0}}
问题是我需要在专业化中使用类似 "A" 的东西,并且无法更改,比方说:
MyClass:MyMotherClass(TypeStruct A);
谢谢
编辑:
选择的解决方案是使用:
static constexpr TypeStruct A = {{1,0,0},{0,0},{0,0,0,0}};
static constexpr TypeStruct B = {{0,1,0},{0,0},{0,0,0,0}};
static constexpr TypeStruct C = {{0,0,1},{0,0},{0,0,0,0}};
etc...
然而,使用这个像 IAR 和 GCC 一样编译的解决方案,我得到以下 PC lint 消息,优先级:高,类别:4397。
"pc lint constexpr variable 'A' must be initialized by a constant expression"
"pc lint constexpr variable 'B' must be initialized by a constant expression"
"pc lint constexpr variable 'C' must be initialized by a constant expression"
正在对位域结构应用初始化,因为它首先在联合中声明。 (将 uint8_t 数据成员放在第一位,警告就会消失)。结果 0x02 和 0x04 对于第一个成员 (uint8_t a) 来说太大了。
您可以通过显式指定位域初始化来解决此问题,例如
static constexpr TypeStruct B = {{0,1},0,0};
static constexpr TypeStruct C = {{0,0,1},0,0};
请注意,一般来说,不能保证位域对应于字节(或其他整数类型)中的位位置 - 这取决于编译器。因此,使用字节值(如 0x02 和 0x04)直接初始化位域结构一开始并不是一个好主意。
使用 IAR 和 GCC 编译代码并避免 PC-lint 错误 #4397 的解决方案:
应使用 static const
而不是 static constexpr
static const TypeStruct A = {{1,0,0},{0,0},{0,0,0,0}};
static const TypeStruct B = {{0,1,0},{0,0},{0,0,0,0}};
static const TypeStruct C = {{0,0,1},{0,0},{0,0,0,0}};
static const TypeStruct D = {{0,0,1},{1,0},{0,0,0,0}};
etc...
我有以下代码 (c++11) :
#include <iostream>
using namespace std;
//Icons
typedef struct
{
union
{
struct
{
uint8_t a : 1;
uint8_t b : 1;
uint8_t c : 1;
uint8_t : 5;
};
uint8_t Data;
} Bla;
union
{
struct
{
uint8_t d : 1;
uint8_t e : 1;
uint8_t : 6;
};
uint8_t Data;
} Foo;
union
{
struct
{
uint8_t f : 1;
uint8_t g : 1;
uint8_t h : 1;
uint8_t i : 1;
uint8_t : 4;
};
uint8_t Data;
} Bar;
}TypeStruct;
int main()
{
static constexpr TypeStruct NONE = {0x00,0,0};
static constexpr TypeStruct A = {0x01,0,0};
static constexpr TypeStruct B = {0x02,0,0};
static constexpr TypeStruct C = {0x04,0,0};
return 0;
}
在 IAR 上编译和工作正常,但在迂腐的 GCC 下,我收到以下错误,这困扰了我几天...
$g++ -std=c++11 -o main *.cpp
main.cpp: In function ‘int main()’:
main.cpp:50:52: warning: large integer implicitly truncated to unsigned type [-Woverflow]
static constexpr TypeStruct B = {0x02,0,0};
^
main.cpp:51:52: warning: large integer implicitly truncated to unsigned type [-Woverflow]
static constexpr TypeStruct C = {0x04,0,0};
^
我不明白为什么! 也许与 union 有关,但我尝试了不同的着作,但没有匹配: {1,0,0} 或 {{1},{0},{0}} 或 {{1,0,0}} 问题是我需要在专业化中使用类似 "A" 的东西,并且无法更改,比方说:
MyClass:MyMotherClass(TypeStruct A);
谢谢
编辑: 选择的解决方案是使用:
static constexpr TypeStruct A = {{1,0,0},{0,0},{0,0,0,0}};
static constexpr TypeStruct B = {{0,1,0},{0,0},{0,0,0,0}};
static constexpr TypeStruct C = {{0,0,1},{0,0},{0,0,0,0}};
etc...
然而,使用这个像 IAR 和 GCC 一样编译的解决方案,我得到以下 PC lint 消息,优先级:高,类别:4397。
"pc lint constexpr variable 'A' must be initialized by a constant expression"
"pc lint constexpr variable 'B' must be initialized by a constant expression"
"pc lint constexpr variable 'C' must be initialized by a constant expression"
正在对位域结构应用初始化,因为它首先在联合中声明。 (将 uint8_t 数据成员放在第一位,警告就会消失)。结果 0x02 和 0x04 对于第一个成员 (uint8_t a) 来说太大了。
您可以通过显式指定位域初始化来解决此问题,例如
static constexpr TypeStruct B = {{0,1},0,0};
static constexpr TypeStruct C = {{0,0,1},0,0};
请注意,一般来说,不能保证位域对应于字节(或其他整数类型)中的位位置 - 这取决于编译器。因此,使用字节值(如 0x02 和 0x04)直接初始化位域结构一开始并不是一个好主意。
使用 IAR 和 GCC 编译代码并避免 PC-lint 错误 #4397 的解决方案:
应使用static const
而不是 static constexpr
static const TypeStruct A = {{1,0,0},{0,0},{0,0,0,0}};
static const TypeStruct B = {{0,1,0},{0,0},{0,0,0,0}};
static const TypeStruct C = {{0,0,1},{0,0},{0,0,0,0}};
static const TypeStruct D = {{0,0,1},{1,0},{0,0,0,0}};
etc...