анонимное объединение в списке инициализаторов: неправильно обрабатывать типы
этот код работает странно, я объясню:
нечего сказать в отношении пунктов 1 и 2, работает perfeclty
однако поведение, упомянутое в пунктах 3 и 4, изменяется:
1) сначала, если я определю:
union {
uint64_t integer ;
double real;
} ;
компилятор показывает мне ошибку о узкая конверсия Между (double) и (uint64_t), но оба имеют одинаковый размер, как вы можете в инструкции assert.
C:\prj\cd>g++ -std=c++11 src\prova.cpp -o bin\main.exe
src\prova.cpp: In function 'int main()':
src\prova.cpp:35:6: error: narrowing conversion of '3.3999999999999999e+0' from 'double' to 'uint64_t {aka long long unsigned int}' inside { } [-Wnarrowing]
t1 = { 1 ,"a",3.4 } ;
^
2) во-вторых, если я изменяю типы заказов, компилятор не выдает ошибку, но после выполнения показывает мне неопределенный результат в точке # 4
union {
double real;
uint64_t integer ;
} ;
консольный вывод:
C:\prj\cd>bin\main.exe
6.6
3
3.4
4611686018427387904
Мы знаем об ошибках в g ++ 5.3 список инициализаторов в C ++ 14, как вы можете найти в bugzilla:
t1 = { 1 ,"a",{ .real=3.4} } ;
Это другие ошибки или странно неопределенное поведение?
здесь другие ссылки о сужении конверсии:
При инициализации списка требуется сужающее преобразование
Сужающие преобразования в C ++ 0x. Это только я, или это звучит как прорыв?
исходный код :
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
typedef struct token_s
{
uint8_t sym ;
std::string tok ;
union {
double real;
uint64_t integer ;
} ;
} token_t ;
int main ( void )
{
assert ( sizeof(uint64_t)==sizeof(double) ) ;
token_t t1 ;
//#1
t1.real = 6.6 ; // ok
std::cout << t1.real << "\n" ;
//#2
t1.integer = 3 ;
std::cout << t1.integer << "\n" ;
//#3
t1 = { 1 ,"a",3.4 } ;
std::cout << t1.real << "\n" ;
//#4
t1 = { 1 ,"a",2 } ;
std::cout << t1.integer << "\n" ;
return 0 ;
}
Задача ещё не решена.
Других решений пока нет …