анонимный союз в списке инициализаторов, неправильно обрабатывает типы - PullRequest
0 голосов
/ 09 мая 2018

анонимный союз в списке инициализаторов: неправильно обрабатывать типы

этот код работает странно, я объясню: нечего сказать в отношении пунктов 1 и 2, работает безупречно

однако поведение, упомянутое в пунктах 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 ;
}
...