Mengapa int x {y = 5} mungkin?

10
int main() {
    int y;
    int x{ y = 5 };
    //x is 5
}

Bagaimana ini mungkin, karena y = 5 bukan ekspresi yang dapat dihitung?

Juga, mengapa kompiler atau IDE tidak mengeluh tentang main () tidak mengembalikan int?

counterstriker0
sumber
8
y = 5 adalah ekspresi, dan memiliki nilai 5. Menurut Anda mengapa tidak?
berguna
2
Sehubungan dengan hilang returndari main, lihat pertanyaan ini .
kenari
3
Lebih baik lagi, hapus pertanyaan kedua. Satu pertanyaan tunggal per pertanyaan adalah model yang disukai pada Stack Overflow.
StoryTeller - Unslander Monica
Mungkin Anda harus mendefinisikan kembali pertanyaan mengapa y = 5menghasilkan 5 di sini. Kemungkinan operator penugasan untuk mengembalikan sesuatu memang fitur aneh dari C / C ++.
user7860670

Jawaban:

11

Saya akan mulai dari pertanyaan terakhir Anda

Juga, mengapa kompiler atau IDE tidak mengeluh tentang main () tidak mengembalikan int?

Menurut Standar C ++ (6.6.1 fungsi utama)

5 Pernyataan return in main memiliki efek meninggalkan fungsi utama (menghancurkan objek dengan durasi penyimpanan otomatis) dan memanggil std :: exit dengan nilai return sebagai argumen. Jika kontrol mengalir dari akhir pernyataan-senyawa utama, efeknya setara dengan pengembalian dengan operan 0 (lihat juga 18.3).

Dan relatif terhadap pertanyaan ini

Bagaimana ini mungkin, karena y = 5 bukan ekspresi yang dapat dihitung?

Dari Standar C ++ (8.18 Operator penugasan dan tugas gabungan)

1 Operator penugasan (=) dan semua operator penugasan gabungan semua grup kanan-ke-kiri. Semua membutuhkan nilai yang dapat dimodifikasi sebagai operan kiri mereka dan mengembalikan nilai yang mengacu pada operan kiri.

Sp deklarasi ini

int x{ y = 5 };

dapat dibagi secara ekivalen menjadi dua pernyataan

y = 5;
int x{ y };

Terlebih lagi dalam C ++ Anda bahkan dapat membuat referensi ke variabel y dengan cara berikut

int &x{ y = 5 };

Ini adalah program demonstratif

#include <iostream>

int main() 
{
    int y;
    int &x{ y = 5 };    

    std::cout << "y = " << y << '\n';

    x = 10;

    std::cout << "y = " << y << '\n';
}

Outputnya adalah

y = 5
y = 10

Anda dapat deklarasi ini

int x{ y = 5 };

menulis ulang juga suka

int x = { y = 5 };

Namun, perhatikan bahwa ada perbedaan antara keduanya (terlihat sama dengan deklarasi di atas) dua deklarasi.

auto x{ y = 5 };

dan

auto x = { y = 5 };

Dalam deklarasi pertama variabel xmemiliki tipe int. Dalam deklarasi kedua variabel xmemiliki tipe std::initializer_list<int>.

Untuk membuat perbedaan lebih terlihat, lihat bagaimana nilai-nilai objek dikeluarkan.

#include <iostream>

int main() 
{
    int y;
    auto x1 { y = 5 };  

    std::cout << "x1 = " << x1 << '\n';

    auto x2 = { y = 10 };   

    std::cout << "*x2.begin()= " << *x2.begin() << '\n';

    std::cout << "y = " << y << '\n';

    return 0;
}

Output program adalah

x1 = 5
*x2.begin()= 10
y = 10
Vlad dari Moskow
sumber
16

Bagaimana ini mungkin, karena y = 5 bukan ekspresi yang dapat dihitung?

Ini adalah tugas, dan tugas menghasilkan nilai-nilai, yaitu "tipe cv-wajar tanpa pengecualian dari operan kiri", lihat [expr.ass / 3] . Oleh karena itu y = 5menghasilkan y, yang 5, yang digunakan untuk menginisialisasi x.

Sehubungan dengan pertanyaan kedua Anda, lihat cppreference di main (atau [basic.start.main / 5] ):

Tubuh fungsi utama tidak perlu mengandung returnpernyataan: jika kontrol mencapai akhir main tanpa menemukan returnpernyataan, efeknya adalah menjalankan return 0;.

Oleh karena itu, kompiler atau IDE memperingatkan Anda tentang returnpernyataan yang hilang pada akhir mainakan menjadi salah. Memang, fakta bahwa Anda harus selalu returnobjek dari non- voidfungsi execptmain adalah jenis ... well, untuk alasan historis kurasa.

lubgr
sumber
2
Ekspresi dapat menghasilkan nilai, tetapi hanya fungsi yang bisa return. -pedantic
Useless
Saya pikir ini int x {y = 5}; pernyataan tidak valid dalam c
bhura
@bhura - pertanyaannya adalah tentang C ++, bukan C
StoryTeller - Unslander Monica
Mungkin layak untuk disebutkan bahwa, meskipun tidak diharuskan, masih mengembalikan nilai dari utama biasanya dianggap praktik yang baik?
Aconcagua
4

The operator=()menghasilkan nilai, yang merupakan nilai yang diberikan untuk variabel. Karena hal ini, dimungkinkan untuk menetapkan tugas seperti ini:

int x, y, z;
x = y = z = 1;
RHertel
sumber
The ekspresi tugas memiliki nilai . Fungsi memiliki nilai balik; ekspresi tidak.
Pete Becker
3

Jika Anda melihat dokumentasi di cppreference , Anda akan melihat bahwa operator=()mengembalikan referensi ke objek yang ditugaskan. Oleh karena itu, tugas dapat digunakan sebagai ekspresi yang mengembalikan objek yang ditugaskan.

Kemudian, itu hanya tugas normal dengan kawat gigi.

Xatyrian
sumber