anonymous union in initializer list : do not handle the types correctly
this code works weirdly, I'll explain : nothing to say regards points 1 and 2, works perfeclty
however the behavior referred to points 3 and 4 changes :
1) first if i define :
union {
uint64_t integer ;
double real;
} ;
compiler shows me error about narrow conversion between (double) and (uint64_t), but both have same size, as you can in in assert instruction.
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) second if i change order types, compiler do not emits error but after execution show me undefined result at point #4
union {
double real;
uint64_t integer ;
} ;
console output :
C:\prj\cd>bin\main.exe
6.6
3
3.4
4611686018427387904
We know about g++ 5.3 bugs referring initializer list in c++14, as you can found in bugzilla :
t1 = { 1 ,"a",{ .real=3.4} } ;
Does is this another bugs or an weirdly undefined behavior ?
here others link about narrowing conversion :
Narrowing Conversion required while list initialization
Narrowing conversions in C++0x. Is it just me, or does this sound like a breaking change?
source code :
#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 ;
}
Aucun commentaire:
Enregistrer un commentaire