C ++使用int截断的神秘结构赋值

问题描述 投票:0回答:2

我有以下代码(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};
                                                    ^

我不明白为什么!也许与联盟有关但我尝试了不同的着作而没有匹配:{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"
c++ struct unions
2个回答
3
投票

初始化将应用于位域结构,因为它在联合中首先声明。 (首先放置uint8_t数据成员,然后看警告消失)。因此,对于第一个成员(uint8_t a),0x02和0x04太大。

您可以通过明确指定位域初始化来解决此问题,例如:

static constexpr TypeStruct B   =   {{0,1},0,0};     
static constexpr TypeStruct C   =   {{0,0,1},0,0};    

注意,通常,不能保证位域将与字节(或其他整数类型)中的位位置相对应 - 这取决于编译器。因此,使用字节值(如0x02和0x04)对位域结构进行直接初始化是一个不好的想法。


0
投票

使用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...
© www.soinside.com 2019 - 2024. All rights reserved.