Re: union { int (Foo::*cFunc ) (); void *void_func;}
От: lxa http://aliakseis.livejournal.com
Дата: 04.02.14 20:23
Оценка:
На всякий случай ссылки, возможно, пригодятся:
здесь
здесь
Re[2]: union { int (Foo::*cFunc ) (); void *void_func;}
От: lxa http://aliakseis.livejournal.com
Дата: 04.02.14 20:37
Оценка:
Ну, этот пример и не обязан работать не с MSVC. А так, конечно, хак, но ведь мог бы помочь писать тесты: здесь
Re[8]: union { int (Foo::*cFunc ) (); void *void_func;}
От: rusted Беларусь  
Дата: 04.02.14 20:43
Оценка:
Здравствуйте, Yotce, Вы писали:

Y>>
Y>>void f() 
Y>>{
Y>>    union 
Y>>    { 
Y>>        int a; 
Y>>        const char* p; 
Y>>    };
Y>>    a = 1;
Y>>    p = "Jennifer";
Y>>    /// то a уже не можем быть равна 1

Y>>    char buf[100];
Y>>    memcpy( &a, buf, strlen("Jennifer\0") ) /// в предыдущем посте тут ошибочку зделал

Y>>    ///*buf == *p;
Y>>}
Y>>


"ошибочку зделал", но так и не исправил полностью
Но вобщем понятно, что хотел показать. Так вот — при сборке с оптимизацией вполне может оказаться, что a все еще будет равно 1. Даже если сейчас всё работает, то с обновлением компилятора может внезапно прострелить тебе ногу.
Re: union { int (Foo::*cFunc ) (); void *void_func;}
От: nen777w  
Дата: 04.02.14 21:14
Оценка:
Уже много ответили, я просто добавлю это
Re[9]: union { int (Foo::*cFunc ) (); void *void_func;}
От: Yotce  
Дата: 05.02.14 07:40
Оценка:
Здравствуйте, rusted, Вы писали:

R> ...

R>"ошибочку зделал", но так и не исправил полностью
R>Но вобщем понятно, что хотел показать. Так вот — при сборке с оптимизацией вполне может оказаться, что a все еще будет равно 1. Даже если сейчас всё работает, то с обновлением компилятора может внезапно прострелить тебе ногу.

R> Так вот — при сборке с оптимизацией вполне может оказаться, что a все еще будет равно 1.

Быть всё таки такого не может два объекта в нашем мире не могу занимать одно и тоже пространство.
По стандарту адрес a и адрес *p равны



R> Даже если сейчас всё работает, то с обновлением компилятора может внезапно прострелить тебе ногу.

Меня и интересует это, в каких случаях это будет работать в каких нет И правильно ли это по стандарту ?
Re[10]: union { int (Foo::*cFunc ) (); void *void_func;}
От: Хреннос  
Дата: 05.02.14 09:47
Оценка:
Здравствуйте, Yotce, Вы писали:

R>> Так вот — при сборке с оптимизацией вполне может оказаться, что a все еще будет равно 1.

Y>Быть всё таки такого не может два объекта в нашем мире не могу занимать одно и тоже пространство.

Сказано же — с оптимизацией. Разработчики компилятора могли прочитать стандарт буквально, и компилятор может подразумевать, что переменные a и p не связаны логически.
Оптимизация может, например, поместить копию значения из а в регистр процессора, чтобы два раза и памяти не читать.

Y>По стандарту адрес a и адрес *p равны


По стандарту равны адреса членов юниона — т.е. в вашем случае это a и p.
В вашем "ошибочку зделал" вы переписываете строку "Jennifer\0" прямо поверх содержимого юниона (а не по адресу, хранящемуся в а, как вам, очевидно, хотелось бы). При этом вы практически гарантированно выходите за его границу и перетираете данные, расположенные далее в стеке (длина строки Jennifer — 8 байт + терминальный нуль, что как минимум на 1 байт больше, чем размер пойнтера в 64-битной машине).
Кстати, у строковых констант терминальный нуль указывать не нужно, он автоматически вставляется компилятором.

R>> Даже если сейчас всё работает, то с обновлением компилятора может внезапно прострелить тебе ногу.

Y>Меня и интересует это, в каких случаях это будет работать в каких нет И правильно ли это по стандарту ?

По стандарту это правильно.
В каких случаях это будет работать? Зависит от того, что именно вы подразумеваете под словами "это" и "работать".
Если "это" означает, что вы пишете в один из членов юниона, а потом читаете из другого — это может работать, а может и нет. Зависит от того, какой именно результат вы хотите получить и как именно вы хотите его использовать.

В качестве примера работающего кода, использующего юнионы, могу предложить такую вот функцию:

bool IsLittleEndianCPU()
{
   union {
      int a;
      char b[sizeof(int)];
  } u;
  u.a = 1;
  return u.b[0] != 0;
}


Этот код работает, и даже почти безопасен (с оговоркой про гипотетические оптимизации компилятора).
Жопа этого кода в том, что он бесполезен и не нужен в реальной жизни: порядок байт в слове известен еще в процессе компиляции, и нет никакого смысла его определять в рантайме.

Но здесь, заметим, работа идет исключительно с целыми числами. Работать так с пойнтерами небезопасно, а работать так с пойнтерами на функции-члены класса (да еще и не совсем понимая, что такое пойнтер и какие они бывают) — прямой путь к глюкам.
Re[11]: union { int (Foo::*cFunc ) (); void *void_func;}
От: Yotce  
Дата: 05.02.14 13:52
Оценка:
Здравствуйте, Хреннос, Вы писали:

Х>Здравствуйте, Yotce, Вы писали:


R>>> Так вот — при сборке с оптимизацией вполне может оказаться, что a все еще будет равно 1.

Y>>Быть всё таки такого не может два объекта в нашем мире не могу занимать одно и тоже пространство.

Х>Сказано же — с оптимизацией. Разработчики компилятора могли прочитать стандарт буквально, и компилятор может подразумевать, что переменные a и p не связаны логически.

Да они могут быть не связаны логически они связаны одним адресом

Х>Оптимизация может, например, поместить копию значения из а в регистр процессора, чтобы два раза и памяти не читать.


Y>>По стандарту адрес a и адрес *p равны


Х>По стандарту равны адреса членов юниона — т.е. в вашем случае это a и p.


да согласен.

Х>В вашем "ошибочку зделал" вы переписываете строку "Jennifer\0" прямо поверх содержимого юниона (а не по адресу, хранящемуся в а, как вам, очевидно, хотелось бы). При этом вы практически гарантированно выходите за его границу и перетираете данные, расположенные далее в стеке (длина строки Jennifer — 8 байт + терминальный нуль, что как минимум на 1 байт больше, чем размер пойнтера в 64-битной машине).

Х>Кстати, у строковых констант терминальный нуль указывать не нужно, он автоматически вставляется компилятором.

Кто — то ошибку заметил Rusted, улыбнулся и понял что хотели сказать...

Х>По стандарту это правильно.

Х>В каких случаях это будет работать? Зависит от того, что именно вы подразумеваете под словами "это" и "работать".
Х>Если "это" означает, что вы пишете в один из членов юниона, а потом читаете из другого — это может работать, а может и нет. Зависит от того, какой именно результат вы хотите получить и как именно вы хотите его использовать.

Х>В качестве примера работающего кода, использующего юнионы, могу предложить такую вот функцию:


Х>
Х>bool IsLittleEndianCPU()
Х>{
Х>   union {
Х>      int a;
Х>      char b[sizeof(int)];
Х>  } u;
Х>  u.a = 1;
Х>  return u.b[0] != 0;
Х>}
Х>


Х>Этот код работает, и даже почти безопасен (с оговоркой про гипотетические оптимизации компилятора).

Х>Жопа этого кода в том, что он бесполезен и не нужен в реальной жизни: порядок байт в слове известен еще в процессе компиляции, и нет никакого смысла его определять в рантайме.

Причем здесь попугаи ой порядок следования байт?

Х>Но здесь, заметим, работа идет исключительно с целыми числами. Работать так с пойнтерами небезопасно, а работать так с пойнтерами на функции-члены класса (да еще и не совсем понимая, что такое пойнтер и какие они бывают) — прямой путь к глюкам.


А где написано что так делать нельзя?
здесь
Re[12]: union { int (Foo::*cFunc ) (); void *void_func;}
От: Хреннос  
Дата: 05.02.14 14:26
Оценка:
Здравствуйте, Yotce, Вы писали:

Y>Да они могут быть не связаны логически они связаны одним адресом


Стандарт, вроде бы, ясно дает понять: на связь "одним адресом" в юнионах закладываться не стоит.

Y>Кто — то ошибку заметил Rusted, улыбнулся и понял что хотели сказать...


Я тоже заметил и тоже понял.
Но это, к сожалению, не просто опечатка, т.к. ровно ту же ошибку вы воспроизвели в "исправленном" варианте.
Кроме того, из ваших пояснений к коду видно, что ваше понимание пойнтеров и работы с ними, скажем так, не отличается кристальной ясностью (путаете адрес переменной и ее содержимое, не видите проблемы в том, что размеры указателей разных типов могут отличаться, спокойно используете int в качестве контейнера для указателя). Именно поэтому я не прошел мимо, как Rusted, а попытался объяснить подробнее.

Y>Причем здесь попугаи ой порядок следования байт?


Это была иллюстрация "почти легального" использования юнионов для получения машинно-зависимой информации.

Х>>Но здесь, заметим, работа идет исключительно с целыми числами. Работать так с пойнтерами небезопасно, а работать так с пойнтерами на функции-члены класса (да еще и не совсем понимая, что такое пойнтер и какие они бывают) — прямой путь к глюкам.


Y>А где написано что так делать нельзя?


"Делать так" — это, возвращаясь к вашему первому посту, использовать обычный указатель, совмещенный с областью хранения указателя на нестатическую функцию-член класса, для чтения и модификации этого указателя на нестатическую функцию-член класса.

В приведенных мной ссылках явно написано, что эти два типа указателей несовместимы между собой, и то, что вы хотите, в общем случае работать не будет (в частных — может и сработать, если повезет).

Текст стандарта только подтверждает вышесказанное.

Y>здесь


Нельзя ли вкратце пояснить, что сей код иллюстрирует, и каким именно образом?
Re[13]: union { int (Foo::*cFunc ) (); void *void_func;}
От: Yotce  
Дата: 05.02.14 15:29
Оценка:
Здравствуйте, Хреннос, Вы писали:

Х>Здравствуйте, Yotce, Вы писали:


Y>>Да они могут быть не связаны логически они связаны одним адресом


Х>Стандарт, вроде бы, ясно дает понять: на связь "одним адресом" в юнионах закладываться не стоит.


Можно конкретные где это написано в стандарте?

Y>>Кто — то ошибку заметил Rusted, улыбнулся и понял что хотели сказать...


Х>Я тоже заметил и тоже понял.

Х>Но это, к сожалению, не просто опечатка, т.к. ровно ту же ошибку вы воспроизвели в "исправленном" варианте.
Х>Кроме того, из ваших пояснений к коду видно, что ваше понимание пойнтеров и работы с ними, скажем так, не отличается кристальной ясностью (путаете адрес переменной и ее содержимое, не видите проблемы в том, что размеры указателей разных типов могут отличаться, спокойно используете int в качестве контейнера для указателя). Именно поэтому я не прошел мимо, как Rusted, а попытался объяснить подробнее.

Не будем разводить демагогию.

Y>>Причем здесь попугаи ой порядок следования байт?


Х>Это была иллюстрация "почти легального" использования юнионов для получения машинно-зависимой информации.


В моём понимании машина не знает да ей и все равно как компилятор представляет указатель на метод класса.

Х>>>Но здесь, заметим, работа идет исключительно с целыми числами. Работать так с пойнтерами небезопасно, а работать так с пойнтерами на функции-члены класса (да еще и не совсем понимая, что такое пойнтер и какие они бывают) — прямой путь к глюкам.


Y>>А где написано что так делать нельзя?


Х>"Делать так" — это, возвращаясь к вашему первому посту, использовать обычный указатель, совмещенный с областью хранения указателя на нестатическую функцию-член класса, для чтения и модификации этого указателя на нестатическую функцию-член класса.


Я НЕ где НЕ утверждал что это правильно.
    union 
    {   int ( __stdcall IObject::*Method )( int, float );  
        void  *void_func; 
    };

Я видел такое преобразование в библиотеки "Rpc — чего там" к сожалению не помню её названия, щас её найти не могу.
Вот и возник вопрос о том на какие грабли можно наступить если использовать такую запись. То что sizeof ( void_func ) != sizeof ( Methos ) и так понятно. Если-бы этого не знал то и вопроса не было-бы...
Но почему Вы говорите что нельзя скопировать?

Х>В приведенных мной ссылках явно написано, что эти два типа указателей несовместимы между собой, и то, что вы хотите, в общем случае работать не будет (в частных — может и сработать, если повезет).


Вы говорите, что
Х>Текст стандарта только подтверждает вышесказанное.
можно увидеть текст стандарта где это написано, желательно с разъяснениями почему Вы понимаете это так?

Y>>здесь


Х>Нельзя ли вкратце пояснить, что сей код иллюстрирует, и каким именно образом?

В моем понимании этот код иллюстрирует сохранение указателя на функцию-член класса
Re[14]: union { int (Foo::*cFunc ) (); void *void_func;}
От: Хреннос  
Дата: 05.02.14 16:56
Оценка:
Здравствуйте, Yotce, Вы писали:

Х>>Стандарт, вроде бы, ясно дает понять: на связь "одним адресом" в юнионах закладываться не стоит.


Y>Можно конкретные где это написано в стандарте?


Вам уже писали
Автор: andyp
Дата: 04.02.14
:

9.5 Unions [class.union]
1 In a union, at most one of the non-static data members can be active at any time, that is, the value of at
most one of the non-static data members can be stored in a union at any time.


Сие означает буквально следующее: писать в один дата мембер, а потом читать эти данные из другого — неопределенное поведение.

Y>>>Причем здесь попугаи ой порядок следования байт?


Х>>Это была иллюстрация "почти легального" использования юнионов для получения машинно-зависимой информации.


Y>В моём понимании машина не знает да ей и все равно как компилятор представляет указатель на метод класса.


К чему это?
В приведенном мной примере нет ни одного указателя.

Y>Я НЕ где НЕ утверждал что это правильно.

Y>
Y>    union 
Y>    {   int ( __stdcall IObject::*Method )( int, float );  
Y>        void  *void_func; 
Y>    };
Y>

Y>Я видел такое преобразование в библиотеки "Rpc — чего там" к сожалению не помню её названия, щас её найти не могу.
Y>Вот и возник вопрос о том на какие грабли можно наступить если использовать такую запись. То что sizeof ( void_func ) != sizeof ( Methos ) и так понятно. Если-бы этого не знал то и вопроса не было-бы...

В таком случае ответ для вас должен быть очевиден, и я не понимаю, зачем вы здесь разводите дискуссию в стиле "поднимите мне веки и процитируйте стандарт".

Грабли — как обычно:
1. На одном компиляторе этот код работает, при попытке перейти на другой компилятор/ОС/архитектуру процессора он может привести к глюкам программы.
2. Даже если код заработает под другим компилятором в тестовом примере, не факт, что в реальном большом проекте он не вызовет появление странных глюков.

В принципе, этого достаточно, чтобы закрыть дискуссию о том, имеет ли смысл использовать такие трюки с юнионами в рабочем коде.

Что касается кода библиотеки — там свои причуды. Она, скорее всего, разрабатывалась под конкретный компилятор и ОС, поэтому авторы не сильно пеклись о переносимости кода и о соблюдении стандартов. Работает — и ладно.

Y>Но почему Вы говорите что нельзя скопировать?


Потому что в приведенном вами коде копирование происходит потенциально неполное: копируется только часть "большого" указателя (то, что поместилось в обычный).

Х>>В приведенных мной ссылках явно написано, что эти два типа указателей несовместимы между собой, и то, что вы хотите, в общем случае работать не будет (в частных — может и сработать, если повезет).


Y>Вы говорите, что

Х>>Текст стандарта только подтверждает вышесказанное.
Y>можно увидеть текст стандарта где это написано, желательно с разъяснениями почему Вы понимаете это так?

О, мне не трудно, я повторю еще раз:

9.5 Unions [class.union]
1 In a union, at most one of the non-static data members can be active at any time, that is, the value of at
most one of the non-static data members can be stored in a union at any time.


Для меня сие означает буквально следующее: писать в один дата мембер, а потом читать эти данные из другого — неопределенное поведение.

Y>>>здесь


Х>>Нельзя ли вкратце пояснить, что сей код иллюстрирует, и каким именно образом?

Y> В моем понимании этот код иллюстрирует сохранение указателя на функцию-член класса

Искал там слово union, не нашел.
Re[15]: union { int (Foo::*cFunc ) (); void *void_func;}
От: Yotce  
Дата: 05.02.14 19:17
Оценка:
Здравствуйте, Хреннос, Вы писали:

Х>Здравствуйте, Yotce, Вы писали:


Х>>>Стандарт, вроде бы, ясно дает понять: на связь "одним адресом" в юнионах закладываться не стоит.


Y>>Можно конкретные где это написано в стандарте?


Х>Вам уже писали
Автор: andyp
Дата: 04.02.14
:


Х>

Х>9.5 Unions [class.union]
Х>1 In a union, at most one of the non-static data members can be active at any time, that is, the value of at
Х>most one of the non-static data members can be stored in a union at any time.


Х>Сие означает буквально следующее: писать в один дата мембер, а потом читать эти данные из другого — неопределенное поведение.


Для меня сие означает, В объединение, не более одного из не-статические члены данных может быть активен в любое время, то есть,
в любое время может хранить не более одного из не-статических членов данных.

Я не претендую что это дословный перевод, но тут негде не говорится что писать в один дата мембер, а потом читать эти данные из другого — неопределенное поведение.
В моём понимании тут говорят про то что если
union __u_t
    {
       static int  s_a; ///     static member
              int  a;   /// non-static member
              char c;   /// non-static member
    } obj;
   int __u_t::s_a = 10;
   obj.a= 100;
   obj.c='c';
 /// И для меня сие означает что нельзя рассчитывать на то что a=100;


здесь
Re[14]: union { int (Foo::*cFunc ) (); void *void_func;}
От: Fuz  
Дата: 05.02.14 20:58
Оценка: 1 (1)
Здравствуйте, Yotce, Вы писали:

Х>>Текст стандарта только подтверждает вышесказанное.

Y>можно увидеть текст стандарта где это написано, желательно с разъяснениями почему Вы понимаете это так?

Вот у тебя есть например:

union
{
бомба,
картофелина
}


Тебе кладут туда бомбу, а ты думаешь что это картофелина и кладешь на сковороду... а по факту там бомба.

В стандарте это описано тут:

3.10/10
If a program attempts to access the stored value of an object through a glvalue of other than one of the
following types the behavior is undefined
:
— the dynamic type of the object,
— a cv-qualified version of the dynamic type of the object,
— a type similar (as defined in 4.4) to the dynamic type of the object,
— a type that is the signed or unsigned type corresponding to the dynamic type of the object,
— a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type
of the object,
— an aggregate or union type that includes one of the aforementioned types among its elements or nonstatic
data members (including, recursively, an element or non-static data member of a subaggregate
or contained union),
— a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,
— a char or unsigned char type.


Как можно земетить, в некоторых случаях так можно делать.
Re[16]: union { int (Foo::*cFunc ) (); void *void_func;}
От: Хреннос  
Дата: 06.02.14 08:00
Оценка:
Здравствуйте, Yotce, Вы писали:

Y>Для меня сие означает, В объединение, не более одного из не-статические члены данных может быть активен в любое время, то есть,

Y>в любое время может хранить не более одного из не-статических членов данных.

"Активен" подразумевает доступ к данным, а не просто их пассивное хранение. Впрочем, это несущественная тонкость.

По сути, запись данных через один мембер, а чтение через другой, эквивалентно приведению "сырого" указателя на данные к целевому типу с последующим разыменованием.
Т.е. примерно так:

#include <iostream>
using namespace std;
  
int main()
{

    union {
       float a;
       int b;
    } u;

    u.a = 100.0;
    cout << "u.b=" << u.b << endl;
    // эквивалентный метод доступа - через касты по сырому указателю
    cout << "casts=" << *reinterpret_cast<int*>(reinterpret_cast<void*>(&u.a)) << endl;
}


Вывод:
u.b=1120403456
casts=1120403456

Тут надо обратить внимание на то, что данные берутся "сырые" — т.е. компилятор не знает ничего об этих данных, и берет их "как есть". В некоторых случаях это приводит к неопределенному поведению (где конкретно — говорит стандарт
Автор: Fuz
Дата: 06.02.14
).
Например, при работе с указателями вовнутрь объекта с множественным наследованием, компилятор иногда пользуется своим знанием об объекте-потомке. При этом компилятор может подправить указатель так, чтобы он смотрел на нужную часть объекта. Если лезть к указателю через поле в юнионе, никаких аджастментов не будет. Пример правки указателей компилятором — тут.

И кстати, если в юнионе хранится нетривиальный объект (с конструктором), то никаких автоматических вызовов конструктора-деструктора при первом доступе к полю компилятор не сгенерирует (я это к содержимому вот этого вашего поста
Автор: Yotce
Дата: 04.02.14
). Надеюсь, вы в том посте пошутили, и в голове у вас все-таки не такой беспросветный мрак.

В юнионе нельзя хранить нетривиальные объекты (non-POD). Точнее, в стандарте С++11 кое-какие поблажки сделали, но несущественные (никаких автоматических вызовов конструктора нет и не будет).
Re[15]: union { int (Foo::*cFunc ) (); void *void_func;}
От: Yotce  
Дата: 06.02.14 08:02
Оценка:
Здравствуйте, Fuz, Вы писали:

Fuz>Здравствуйте, Yotce, Вы писали:


Х>>>Текст стандарта только подтверждает вышесказанное.

Y>>можно увидеть текст стандарта где это написано, желательно с разъяснениями почему Вы понимаете это так?

Fuz>Вот у тебя есть например:

Fuz>

Fuz>union
Fuz>{
Fuz> бомба,
Fuz> картофелина
Fuz>}


Fuz>Тебе кладут туда бомбу, а ты думаешь что это картофелина и кладешь на сковороду... а по факту там бомба.


В том-то и дело туда с начало положили бомбу потом её заменили на картофель, почему там должна быть бомба?

Fuz>В стандарте это описано тут:


Fuz>

3.10/10
Fuz>If a program attempts to access the stored value of an object through a glvalue of other than one of the
Fuz>following types the behavior is undefined
:
Fuz> — the dynamic type of the object,
Fuz> — a cv-qualified version of the dynamic type of the object,
Fuz> — a type similar (as defined in 4.4) to the dynamic type of the object,
Fuz> — a type that is the signed or unsigned type corresponding to the dynamic type of the object,
Fuz> — a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type
Fuz> of the object,
Fuz> — an aggregate or union type that includes one of the aforementioned types among its elements or nonstatic
Fuz> data members (including, recursively, an element or non-static data member of a subaggregate
Fuz> or contained union),
Fuz> — a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,
Fuz> — a char or unsigned char type.


Не понял причём тут это?
Re[15]: union { int (Foo::*cFunc ) (); void *void_func;}
От: lxa http://aliakseis.livejournal.com
Дата: 06.02.14 08:06
Оценка:
Что-то не так! :)
Re[16]: union { int (Foo::*cFunc ) (); void *void_func;}
От: Fuz  
Дата: 06.02.14 08:49
Оценка:
Здравствуйте, Yotce, Вы писали:

Y>Здравствуйте, Fuz, Вы писали:


Fuz>>Здравствуйте, Yotce, Вы писали:


Х>>>>Текст стандарта только подтверждает вышесказанное.

Y>>>можно увидеть текст стандарта где это написано, желательно с разъяснениями почему Вы понимаете это так?

Fuz>>Вот у тебя есть например:

Fuz>>

Fuz>>union
Fuz>>{
Fuz>> бомба,
Fuz>> картофелина
Fuz>>}


Fuz>>Тебе кладут туда бомбу, а ты думаешь что это картофелина и кладешь на сковороду... а по факту там бомба.


Y>В том-то и дело туда с начало положили бомбу потом её заменили на картофель, почему там должна быть бомба?


Я про этот случай (здесь замены нет):

    union {
       float a;
       int b;
    } u;

    u.a = 100.0; // положили бомбу
    int v = u.b; // ... а достаем как картошку. Но по факту там бомба


'u.b' — это (в нашем случае) initializer expression, которое представляет собой lvalue типа 'int' (5.2.5/3), но объект, на который оно ссылается('u.a') имеет тип 'float' (в union ведь может только один объект храниться)
При выполнении value initialization будет выполнено lvalue-to-rvalue преобразование. Здесь появится UB, т.к. типы не соответствуют (ожидается 'int', а на входе 'float').
Re[17]: union { int (Foo::*cFunc ) (); void *void_func;}
От: Yotce  
Дата: 06.02.14 08:50
Оценка:
Здравствуйте, Хреннос, Вы писали:

Если Кто-то утверждает что трава "зелёная-зелёная" кто-то поверит на слова, а кто-то попытается разобраться в этом. И выяснят что трава "зелёная-зеленая" при определённых обстоятельствах, а ещё бывает "зеленая"... .
Re[16]: union { int (Foo::*cFunc ) (); void *void_func;}
От: Yotce  
Дата: 06.02.14 08:50
Оценка:
Здравствуйте, lxa, Вы писали:

lxa>Что-то не так! :)


Понел. Спс.
Re[18]: union { int (Foo::*cFunc ) (); void *void_func;}
От: uzhas Ниоткуда  
Дата: 06.02.14 08:52
Оценка:
Здравствуйте, Yotce, Вы писали:

Y>трава "зелёная-зелёная"


бросай курить, вставай на лыжи
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.