5

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));
}
YSC
  • 38,212
  • 9
  • 96
  • 149
Harry
  • 2,177
  • 1
  • 19
  • 33
  • What compiler are you on, and what is the compiler error you're getting? Please edit the original question with that information. – Kevin Anderson Nov 26 '18 at 13:02
  • 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)); " – Harry Nov 26 '18 at 13:11

2 Answers2

5

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 an lvalue 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));
O'Neil
  • 3,790
  • 4
  • 16
  • 30
YSC
  • 38,212
  • 9
  • 96
  • 149
1

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));
Nikos C.
  • 50,738
  • 9
  • 71
  • 96