Beberapa compiler C ++ mengizinkan unions dan struct anonim sebagai ekstensi untuk C ++ standar. Ini sedikit gula sintaksis yang terkadang sangat membantu.
Apa alasan yang mencegah ini menjadi bagian dari standar? Apakah ada hambatan teknis? Yang filosofis? Atau hanya tidak cukup kebutuhan untuk membenarkannya?
Inilah contoh dari apa yang saya bicarakan:
struct vector3 {
union {
struct {
float x;
float y;
float z;
};
float v[3];
};
};
Kompiler saya akan menerima ini, tetapi ia memperingatkan bahwa "struct / union tanpa nama" adalah ekstensi non-standar untuk C ++ .
struct { int i; } a; a.i = 0;
(tipe tidak memiliki nama). Yang kedua adalah yang ini, yang tidak didukung C ++ :struct { int i; }; i = 0;
(tipe tidak memiliki nama, dan lolos ke lingkup sekitarnya). C ++, bagaimanapun, tidak mendukung kedua tidak disebutkan namanya dan anonim serikat .Jawaban:
Seperti yang telah ditunjukkan oleh orang lain, serikat anonim diizinkan dalam C ++ standar, tetapi struct anonim tidak.
Alasannya adalah karena C mendukung unions anonim tetapi bukan struct anonim *, jadi C ++ mendukung yang pertama untuk kompatibilitas tetapi bukan yang terakhir karena tidak diperlukan untuk kompatibilitas.
Selain itu, tidak banyak gunanya struct anonim di C ++. Penggunaan Anda menunjukkan, memiliki struct yang berisi tiga mengapung yang dapat disebut baik oleh
.v[i]
, atau.x
,.y
dan.z
, saya percaya hasil dalam perilaku undefined di C ++. C ++ tidak mengizinkan Anda untuk menulis ke salah satu anggota serikat, katakanlah.v[1]
, dan kemudian membaca dari anggota lain, katakanlah.y
. Meskipun kode yang melakukan ini tidak jarang, sebenarnya tidak didefinisikan dengan baik.Fasilitas C ++ untuk tipe yang ditentukan pengguna menyediakan solusi alternatif. Sebagai contoh:
struct vector3 { float v[3]; float &operator[] (int i) { return v[i]; } float &x() { return v[0]; } float &y() { return v[1]; } float &z() { return v[2]; } };
* C11 tampaknya menambahkan struct anonim, sehingga revisi C ++ di masa mendatang dapat menambahkannya.
sumber
Saya akan mengatakan, Anda dapat membersihkan
vector3
deklarasi Anda hanya dengan menggunakanunion
union vector3 { struct { float x, y, z; } ; float v[3] ; } ;
Tentu, struktur anonim adalah ekstensi MSVC . Tetapi ISO C11 mengizinkannya sekarang, dan gcc mengizinkannya , dan begitu pula compiler llvm Apple.
Mengapa di C11 dan bukan C ++ 11? Saya tidak yakin, tetapi secara praktis sebagian besar (gcc ++, MSVC ++ dan kompiler C ++ Apple) C ++ mendukung mereka.
sumber
Tidak yakin apa yang kamu maksud. Bagian 9.5 dari spesifikasi C ++, klausul 2:
Anda juga dapat melakukan hal-hal seperti ini:
void foo() { typedef struct { // unnamed, is that what you mean by anonymous? int a; char b; } MyStructType; // this is more of a "C" style, but valid C++ nonetheless struct { // an anonymous struct, not even typedef'd double x; double y; } point = { 1.0, 3.4 }; }
Tidak selalu sangat berguna ... meskipun terkadang berguna dalam definisi makro yang buruk.
sumber
Serikat pekerja bisa jadi anonim; lihat Standar, 9,5 paragraf 2.
Apa tujuan Anda melihat struct atau class anonim memenuhi? Sebelum berspekulasi mengapa ada sesuatu yang tidak ada dalam Standar, saya ingin tahu mengapa itu harus, dan saya tidak melihat penggunaan untuk struct anonim.
sumber
Berdasarkan hasil edit, komentar, dan artikel MSDN ini: Struktur Anonim , saya akan menebaknya - ini tidak cocok dengan konsep enkapsulasi. Saya tidak akan mengharapkan anggota kelas untuk mengacaukan namespace kelas saya selain hanya menambahkan satu anggota. Selain itu, perubahan pada struktur anonim dapat memengaruhi kelas saya tanpa izin.
sumber
Kode Anda
union { struct { float x; float y; float z; }; float v[3]; };
seperti
union Foo { int; float v[3]; };
yang tentunya tidak valid (di C99 dan sebelumnya).
Alasannya mungkin untuk menyederhanakan penguraian (dalam C), karena dalam hal ini Anda hanya perlu memeriksa bahwa struct / union body hanya memiliki "pernyataan deklarator" seperti
Karena itu, gcc dan "kompiler lain" mendukung kolom tanpa nama sebagai ekstensi.
Sunting: Structs anonim sekarang secara resmi didukung di C11 (§6.7.2.1 / 13).
sumber
union { ... }
berbeda denganstruct { ... }
. Yang pertama valid, tetapi yang terakhir tidak.union { ... };
tidak valid salah.