c++ - Packing structure results in return of reference to local? -
i've got following code, , i'm struggling understand why packing structure causes warning (and subsequently segfault when run.) firstly code:
#include <iostream> using namespace std; template <typename t, std::size_t d, std::size_t s> struct __attribute__((packed)) c { union __attribute__((packed)) valuetype { char fill[s]; t value; }; valuetype data_; const t& get() const { return data_.value; } friend std::ostream& operator<<(std::ostream& str, const c& f) { return str << f.data_.value; } }; template <typename t, std::size_t d> struct __attribute__((packed)) c<t, d, d> { t value; const t& get() const { return value; } friend std::ostream& operator<<(std::ostream& str, const c& f) { return str << f.value; } }; template <typename t, std::size_t s = 0> struct __attribute__((packed)) d { c<t, sizeof(t), s> c; const t& get() const { return c.get(); } friend std::ostream& operator<<(std::ostream& str, const d& f) { return str << f.get(); } }; template <typename t> struct __attribute__((packed)) d<t, 0> { t v; const t& get() const { return v; } friend std::ostream& operator<<(std::ostream& str, const d& f) { return str << f.get(); } }; int main(void) { d<int64_t> d1; cout << d1 << endl; d<int64_t, 8> d2; cout << d2 << endl; } with packing (it's gcc specific) following (gcc 5.2.1/5.3.1, c++14 -wall):
packed.cpp: in instantiation of ‘const t& d<t, 0ul>::get() const [with t = long int]’: packed.cpp:58:16: required ‘std::ostream& operator<<(std::ostream&, const d<long int>&)’ packed.cpp:64:13: required here packed.cpp:53:12: warning: returning reference temporary [-wreturn-local-addr] return v; ^ packed.cpp: in instantiation of ‘const t& c<t, d, d>::get() const [with t = long int; long unsigned int d = 8ul]’: packed.cpp:40:18: required ‘const t& d<t, s>::get() const [with t = long int; long unsigned int s = 8ul]’ packed.cpp:45:16: required ‘std::ostream& operator<<(std::ostream&, const d<long int, 8ul>&)’ packed.cpp:66:13: required here packed.cpp:27:12: warning: returning reference temporary [-wreturn-local-addr] return value; if structures not packed - code compiles , runs fine (prints rubbish value - that's expected.)
so question - why packing cause return of temporary?
what you're looking pragma pack. has same effect want, more common , cross-compiler.
note: adding modified version of code pragma pack
#include <iostream> using namespace std; #pragma pack(1) template <typename t, std::size_t d, std::size_t s> struct c { union valuetype { char fill[s]; t value; }; valuetype data_; const t& get() const { return data_.value; } }; #pragma pack() template <typename t, std::size_t d> struct c<t, d, d> { t value; const t& get() const { return value; } }; template <typename t, std::size_t d> struct c<t, d, 0> { t value; const t& get() const { return value; } }; template <typename t, std::size_t s = 0> struct d : c<t, sizeof(t), s> { friend std::ostream& operator<<(std::ostream& str, const d& f) { return str << f.get(); } }; #pragma pack(1) struct e { d<int16_t> a; d<int64_t, 9> b; }; #pragma pack() int main(void) { d<int16_t> d1; cout << d1.get() << ' ' << sizeof(d1) << endl; d<int64_t, 9> d2; cout << d2.get() << ' ' << sizeof(d2) << endl; cout << sizeof(e) << endl; }
Comments
Post a Comment