Tidak ada peringatan tentang konversi implisit

// g++ sizeofint.cpp --std=c++11 -Wconversion -Wall -Wextra -Werror -pedantic-errors
#include <iostream>
#include <utility>

int main(int argc, char **argv) {
    (void)argc;
    (void)argv;
    int a = 0x12345678;
    std::cout << sizeof(int) << "..." << sizeof(uint16_t) << std::endl;
    std::pair<uint16_t, uint16_t> p{a,a}; // !!!! no warning or error on conversion !!!!
    std::cout << p.first << ":" << p.second << std::endl;
    uint16_t b = a; // !!!! correct behavior: -Wconversion triggers warning, which -Werror turns to an error
    std::cout << b << std::endl;
    return 0;
}

Dengan kode di atas, Anda dapat melihat dengan jelas konversi implisit dari int ke uint16_t saat membuat p. Namun, g++ pada versi 4.9.1 tidak mengeluhkan konversi apa pun saat menggunakan parameter yang disediakan dalam komentar di awal.

Kemudian, g++ mengeluh tentang konversi implisit ke uint16_t saat membuat b.

Saya mencoba memastikan bahwa konstruksi p akan menghasilkan setidaknya peringatan (tetapi sebaiknya kesalahan).

Ada pemikiran? Apakah ada tanda yang saya tidak tahu untuk memicu perilaku yang benar?


person inetknght    schedule 27.08.2014    source sumber
comment
Anda menekan konstruktor template<class U, class V> constexpr pair(U&& x, V&& y); std::pair. Karena konversi sebenarnya terjadi di dalam konstruktor tersebut (di header sistem), Anda tidak mendapat peringatan.   -  person T.C.    schedule 27.08.2014
comment
Jika konstruksinya ada di dalam perpustakaan, saya bisa mengerti. Tapi seperti yang Anda katakan, ini ada dalam templat... yang dikompilasi dan oleh karena itu harus diperiksa.   -  person inetknght    schedule 27.08.2014
comment
@T.C. haruskah itu jawabannya?   -  person Slava    schedule 27.08.2014
comment
dokumen gcc : Semua peringatan, selain yang dihasilkan oleh '#warning ' (lihat Diagnostik), disembunyikan saat GCC memproses header sistem. Lihat contoh Anda yang dimodifikasi memberi Anda peringatan yang diharapkan   -  person quantdev    schedule 27.08.2014
comment
Apakah ada cara untuk mengaktifkan peringatan untuk header sistem?   -  person inetknght    schedule 27.08.2014
comment
@Arkadiy, sayangnya tidak.   -  person inetknght    schedule 27.08.2014
comment
@millsj, terima kasih sudah berhasil. Tentu saja ada banyak omong kosong lainnya sekarang juga... hanya menyoroti betapa banyak keajaiban di balik layar yang diretas bersama-sama. :(   -  person inetknght    schedule 27.08.2014


Jawaban (1)


Jika kode Anda menggunakan konstruktor constexpr pair(const uint16_t& x, const uint16_t& y); dari std::pair<uint16_t, uint16_t>, Anda akan mendapat peringatan dan/atau kesalahan. Anda bahkan tidak memerlukan -Wconversion untuk ini - mempersempit konversi di dalam kurung kurawal membuat program tidak berfungsi.

Namun sebaliknya, resolusi kelebihan beban memilih konstruktor template<class U, class V> constexpr pair(U&& x, V&& y); std::pair, yang lebih cocok. Hasilnya, konversi terjadi, bukan di dalam kode yang Anda tulis, namun di dalam konstruktor tersebut. Karena konstruktor tersebut didefinisikan dalam header sistem (lihat dokumentasi GCC, topi tip @quantdev), peringatan tersebut disembunyikan oleh GCC.

Meskipun Anda dapat menggunakan -Wsystem-headers untuk mengaktifkan peringatan dari header sistem, opsi tersebut akan menghasilkan banyak peringatan yang tidak terkait dan berinteraksi sangat buruk dengan -Werror.

person T.C.    schedule 27.08.2014