Error: "cannot bind packed field" while inserting data into std::map using insert function
Asked Answered
E

2

6

Can somebody tell me the difference between #pragma pack(push,1) and __attribute__((packed))? I am getting a compilation error if I use second type of struct packing which says

cannot bind packed field ‘ABC.abc::a’ to ‘unsigned int&’

But if I use first type of struct packing then there is no compilation error.

This is my sample code:

//DataStructure.h

#ifndef DATASTRUCTURE_H_
#define DATASTRUCTURE_H_

struct abc
{
    unsigned int a;
    float b;
}__attribute__((packed));

#endif /* DATASTRUCTURE_H_ */



//Main.cpp
#include<iostream>
#include<map>
#include "DataStructure.h"


int main()
{
    struct abc ABC;
    ABC.a=3;
    ABC.b=4.6f;

    std::map<unsigned int,struct abc> Mapp;
    Mapp.insert(std::make_pair(ABC.a,ABC));
}
Elmiraelmo answered 26/11, 2018 at 12:58 Comment(2)
What compiler are you on, and what is the compiler error you're getting? Please edit the original question with that information.Therron
I am using GCC compiler "gcc version 4.8.5 20150623". And this is the error I'm getting " cannot bind packed field ‘ABC.abc::a’ to ‘unsigned int&’ Mapp.insert(std::make_pair(ABC.a,ABC)); "Elmiraelmo
B
6

The error comes from:

std::make_pair(ABC.a,ABC);

Since C++11, make_pair is defined as:

template< class T1, class T2 >
std::pair<V1,V2> make_pair( T1&& t, T2&& u );

so giving it ABC.a as first argument is trying to bind a "non-const" reference to a bitfield (what a packed struct is basically), which is illegal.

To solve that, you must create a fresh unsigned int and call make_pair with it:

unsigned int a = ABC.a;
Mapp.insert(std::make_pair(a,ABC));
Ballance answered 26/11, 2018 at 13:39 Comment(3)
but why it is not giving an error if I use the first type of struct packingElmiraelmo
@Elmiraelmo I can't tell, #pragmas are implementation-specified.Ballance
@Ballance "bind an lvalue reference to a bitfield". 1.How to understand the said lvalue reference in the right way? Where's the said lvalue reference? 2. Why lvalue reference can't be bind to bitfield? Here is the simple code snippet to reproduce the error.Curtsy
A
2

You don't need to make a copy by hand. You can use the unary plus operator to force evaluation, which will promote ABC.a to an integer value:

Mapp.insert(std::make_pair(+ABC.a, ABC));
Adaliah answered 25/4, 2022 at 0:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.