Baru-baru ini,
saya diingatkan mengapa saya
menganggap itu ide yang buruk untuk memberikan pemula C ++. Ini adalah
ide yang buruk , karena dalam C ++ kekacauan yang sebenarnya adalah kekacauan yang indah, tetapi sesat, tragis dan menakjubkan. Terlepas dari keadaan komunitas saat ini, artikel ini tidak ditujukan terhadap C ++
modern . Sebaliknya, ia melanjutkan sebagian
artikelnya oleh Simon Brand,
"Inisialisasi dalam C ++ itu gila," dan sebagian itu adalah pesan untuk setiap siswa yang ingin memulai pendidikan mereka melihat ke dalam jurang.
Keberatan siswa yang umum ketika mereka diberitahu tentang belajar C:
- "Apakah ada orang lain yang menggunakannya?"
- "Ini bodoh."
- "Kenapa kita belajar C?"
- βKita harus belajar sesuatu yang lebih baik, misalnya, C ++β ( tertawa )
Tampaknya banyak siswa berpikir bahwa belajar C tidak terlalu penting (dari penulis: tidak) dan harus dimulai dengan C ++. Mari kita lihat salah satu alasan mengapa ini adalah proposisi yang absurd:
membuat variabel sialan . Dalam artikel aslinya, Simon Brand menyarankan agar pembaca sudah terbiasa dengan keanehan inisialisasi dalam versi sebelum C ++ 11. Di sini kita melihat beberapa dari mereka dan melangkah lebih jauh.
Mari saya mulai dengan menjelaskan bahwa dalam artikel ini pendapat pribadi saya, dan
bukan posisi resmi Universitas Drexel, tempat saya mengajar di Departemen Teknik Listrik dan Komputer. Kuliah saya biasanya dimasukkan dalam program teknik, daripada ilmu komputer, yaitu, mereka lebih berhubungan dengan pemrograman sistem dan sistem embedded.
Ringkasan dalam satu GIF
u / AlexAlabuzhev di Reddit berhasil menceritakan kembali seluruh artikel ini dalam satu gif. (Saya pikir ini adalah karya asli dari
Timur Dumler )
Saya tidak menentang C ++, tetapi ada banyak hal yang tidak Anda butuhkan pada tahap awal.
Itu saja. Pulanglah Berjalan-jalan dengan anjing. Cuci cucian. Panggil ibu dan katakan kamu mencintainya. Coba resep baru. Tidak ada yang bisa dibaca di sini, teman-teman. Bahkan, pikirkan betapa buruknya para insinyur (yaitu, saya) mampu menyampaikan pikiran mereka ...
Segalanya, saya meyakinkan sebanyak mungkin!
Jadi, apakah kamu masih di sini? Tentara nyata Jika aku bisa, aku akan memberimu medali! Dan susu coklat yang lezat!
Sekarang kembali ke pemrograman ... biasa kami.Inisialisasi dalam C
Entri
Pertama, pertimbangkan
inisialisasi dalam C karena mirip dengan C ++ karena alasan kompatibilitas. Ini akan sangat cepat, karena C sangat membosankan dan sederhana (
ahem ). Setiap pemula mempelajari inisialisasi ini dengan hati, karena dalam C ia bekerja secara berbeda dari pada banyak bahasa baru yang diketik secara statis. Ada inisialisasi default untuk nilai yang dapat diterima, atau kesalahan kompilasi dilemparkan.
int main() {
int i;
printf("%d", i);
}
C ,
i
(
i
). , ,
int i = 0
;, . ,
, , , , ,
0
.
, .
int i;
int main() {
printf("%d", i);
}
, ?
i
β .
.
, . , ? . , .
, .
struct A {
int i;
};
int main() {
struct A a;
printf("%d", a.i);
}
.
a
. .
$ gcc -Wuninitalized a.c
a.c: In function βmainβ:
a.c:9:5: warning: βa.iβ is used uninitialized in this function [-Wuninitialized]
printf("%d\n", a.i);
C . : 1) , 2) 3) .
struct A {
int i;
} const default_A = {0};
void init_A(struct A *ptr) {
ptr->i = 0;
}
int main() {
/* helper function */
struct A a1;
init_A(&a1);
/* during definition;
* Initialize each member, in order.
* Any other uninitialized members are implicitly
* initialized as if they had static storage duration. */
struct A a2 = {0};
/* Error! (Well, technically) Initializer lists are 'non-empty' */
/* struct A a3 = {}; */
/* ...or use designated initializers if C99 or later */
struct A a4 = {.i = 0};
/* default value */
struct A a5 = default_A;
}
, C, , . , ,
0
.
C++
1.
C++, .
, C ,
.
C++, , , β¦
β¦ C++ C. :
struct A {
int i;
};
int main() {
A a;
std::cout << a.i << std::endl;
}
C++ . C
A
, . C++
a
,
.
A
,
, . Β« Β», :
struct A {
A(){}
int i;
}
, .
g++ 8.2.1
,
clang++ 7.0.1
(
-Wuninitialized
). , .
$ g++ -Wuninitalized -O2 a.cpp
a.cpp: In function βint main()β:
a.cpp:9:20: warning: βa.A::iβ is used uninitialized in this function [-Wuninitialized]
std::cout << a.i << std::endl;
C.
A::i
?
2.
, , ? , C++ , ? (
)
struct A {
int i;
};
int main() {
A a = {.i = 0};
std::cout << a.i << std::endl;
}
$ g++ -Wuninitialized -O2 -pedantic-errors a.cpp
a.cpp: In function βint main()β:
a.cpp:9:12: error: C++ designated initializers only available with -std=c++2a or -std=gnu++2a [-Wpedantic]
A a = {.i = 0};
. C++ C++20. C++, 2020 . , C++ 21 , C. ,
-pedantic-errors
gcc.
?
struct A {
int i;
};
int main() {
A a = {0};
std::cout << a.i << std::endl;
}
$ g++ -Wuninitialized -O2 -pedantic-errors a.cpp
$
.
A a = {};
,
a.i
.
A
. ?
C++11 ( ) C, , C. , , , . . ?
- .
- «».
, ? , . ,
A
, . ,
int i
,
.
! - : ! .
C++11 β¦ .
? , C++ .
. . , , . . , , , .
3.
,
C++
(
)!
i
:
struct A {
A() : i(0) {}
int i;
};
i
. β :
struct A {
A() { i = 0; }
int i;
};
, ( ).
C++11 (, ).
struct A {
int i = 0; // default member initializer, available in C++11 and later
};
, ,
i
0,
A
. , A
i
, . :
struct A {
A(int i = 0) : i(i) {}
int i;
};
int main() {
A a1;
A a2(1);
std::cout << a1.i << " " << a2.i << std::endl;
}
$ g++ -pedantic-errors -Wuninitialized -O2 a.cpp
$ ./a.out
0 1
. A a();
, a
, A
. ? - - , .
! . . C++, . !
4.
. ,
C++, . g++ (8.2.1),
gnu++1y
, C++14 GNU. , g++ C++17. Β« ?Β» β . , .
, C++11, ,
. , ?
. : .
. FAQ:
C++11 , .
(
{thing1, thing2, ...}
,
braced-init-list) :
#include <iostream>
struct A {
int i;
};
int main() {
A a1; // default initialization -- as before
A a2{}; // direct-list-initialization with empty list
A a3 = {}; // copy-list-initialization with empty list
std::cout << a1.i << " " << a2.i << " " << a3.i << std::endl;
}
$ g++ -std=c++11 -pedantic-errors -Wuninitialized -O2 a.cpp
a.cpp: In function βint main()β:
a.cpp:9:26: warning: βa1.A::iβ is used uninitialized in this function [-Wuninitialized]
std::cout << a1.i << " " << a2.i << " " << a3.i Β« std::endl;
, , ?
a1.i
. , , .
A a{};
,
A a = {};
.
a
braced-init-list. ,
A a = {};
β
copy-list-initialization (
). ,
A a;
.
7/8 (,
C++11):
A
.
- , A .
- , .
- int i{}
i
, 0.
?
int main() {
A a1{0};
A a2{{}};
A a3{a1};
std::cout << a1.i << " " << a2.i << " " << a3.i << std::endl;
}
$ g++ -std=c++11 -pedantic-errors -Wuninitialized -O2 a.cpp
$
a1.i
0,
a2.i
,
a3
β ,
a1
. , ,
? , rvalue, , pr-, x-, gl-β¦ , .
, C++11 , C++17 C++20 . , C++, - . . , C++17, . !
? ? ? , , ?
5. ,
,
A
?
, :
- //,
- /
- ( C++11, )
- ( C++17)
- (
using Base::Base;
, C++17)
:
#include <iostream>
struct A {
A(){};
int i;
};
int main() {
A a{};
std::cout << a.i << std::endl;
}
$ g++ -std=c++11 -pedantic-errors -Wuninitialized -O2 a.cpp
a.cpp: In function βint main()β:
a.cpp:8:20: warning: βa.A::iβ is used uninitialized in this function [-Wuninitialized]
std::cout << a.i << std::endl;
A
, .
7 :
A
.- - braced-init-list , .
- , , ,
a.i
.
, ?
struct A {
A() = default;
};
, . , A
.
struct A {
A();
};
A::A() = default;
, . A(){}
,
.
? C++20 : , :). ? ! .
:
#include <iostream>
class A {
int i;
friend int main();
};
int main() {
A a{};
std::cout << a.i << std::endl;
}
A
β , ,
i
,
main
.
. . ,
a.i
, ?
$ g++ -std=c++11 -pedantic-errors -Wuninitialized -O2 a.cpp
$
. , . ,
a.i
0, :
- A, 2.
- , , braced-init-list , 3.
- , , 4.
- , ( ).
:
#include <iostream>
class A {
int i;
friend int main();
};
int main() {
A a = {1};
std::cout << a.i << std::endl;
}
$ g++ -std=c++11 -pedantic-errors -Wuninitialized -O2 a.cpp
a.cpp: In function βint main()β:
a.cpp:7:13: error: could not convert β{1}β from β<brace-enclosed initializer list>β to βAβ
A a = {1};
A
, :
- A, 2.
- .
1
A
, .
:
#include <iostream>
struct A {
A(int i) : i(i) {}
A() = default;
int i;
};
int main() {
A a{};
std::cout << a.i << std::endl;
}
, , , : , A . ,
?
$ g++ -std=c++11 -pedantic-errors -Wuninitialized -O2 a.cpp
$
! :
- A, 2.
- , , braced-init-list , 3.
- ( ), , 4.
- , ( ).
:
#include <iostream>
struct A {
A(){}
int i;
};
struct B : public A {
int j;
};
int main() {
B b = {};
std::cout << b.i << " " << b.j << std::endl;
}
$ g++ -std=c++11 -pedantic-errors -Wuninitialized -O2 a.cpp
a.cpp: In function βint main()β:
a.cpp:11:25: warning: βb.B::<anonymous>.A::iβ is used uninitialized in this function [-Wuninitialized]
std::cout << b.i << " " << b.j << std::endl;
b.j
,
b.i
. ? !
b
.
Stack Overflow,
, , .
. , clang ( ) . .
...
( ) ( ) , !
6.
C++11
std::initializer_list
. : ,
std::initializer_list<T>
. braced-init-list. , braced-init-list . initializer_list braced-init-list! , , . , ! , ?
struct A {
template <typename T>
A(std::initializer_list<T>) {}
int i;
};
int main() {
A a1{0};
A a2{1, 2, 3};
A a3{"hey", "thanks", "for", "reading!"};
std::cout << a1.i << a2.i << a3.i << std::endl;
}
$ g++ -std=c++17 -pedantic-errors -Wuninitialized -O2 a.cpp
a.cpp: In function βint main()β:
a.cpp:12:21: warning: βa1.A::iβ is used uninitialized in this function [-Wuninitialized]
std::cout << a1.i << a2.i << a3.i << std::endl;
^
a.cpp:12:29: warning: βa2.A::iβ is used uninitialized in this function [-Wuninitialized]
std::cout << a1.i << a2.i << a3.i << std::endl;
^
a.cpp:12:37: warning: βa3.A::iβ is used uninitialized in this function [-Wuninitialized]
std::cout << a1.i << a2.i << a3.i << std::endl;
.
A
,
std::initializer_list<T>
. , , ,
i
.
T
, .
- ,
{0}
std::initializer_list<int>
0
. {1, 2, 3}
std::initializer_list<int>
.- braced-init-list
std::initializer_list<const char*>
.
: A a{}
, . , a{std::initializer_list<int> {}}
. , A(std::initializer_list<int>){}
.
std::initializer_list
STL, :
size
,
begin
end
.
begin
end
, . , :
#include <vector>
#include <string>
int main() {
std::vector<int> v_1_int{5};
std::vector<int> v_5_ints(5);
std::vector<std::string> v_strs = {"neato!", "blammo!", "whammo!", "egh"};
}
std::vector<T>
,
std::initializer_list<T>
, , .
. v_1_int
, std::initializer_list<int< init
5
.
v_5_ints
size_t count
, (5
) ( 0
).
β, :
#include <iostream>
struct A {
A(std::initializer_list<int> l) : i(2) {}
A(int i = 1) : i(i) {}
int i;
};
int main() {
A a1;
A a2{};
A a3(3);
A a4 = {5};
A a5{4, 3, 2};
std::cout << a1.i << " "
<< a2.i << " "
<< a3.i << " "
<< a4.i << " "
<< a5.i << std::endl;
}
, . :
std::initializer_list<int>
,
int
. , ,
i
.
...? , .
$ g++ -std=c++11 -pedantic-errors -Wuninitialized -O2 a.cpp
$ ./a.out
1 1 3 2 2
a1
. , , .
a2
.
A
( ), .
A
, .
a3
, braced-init-list,
3
,
int
. ,
4
, ,
std::initializer_list
. ,
a5
-
int
, ,
a4
.
, , (
) , , . , , . ++, .
, β . , . , . , -, , ,
.
, , C++ , ( ). .
. , 5 .
18 .
C++. , , . C++, C++, , .
C C ,
this
C.
C β , , , . 18 .
, ,
. .
:
- Lobste.rs
- Hacker News
- Reddit
: ,
. , β . , C++. . , STL C, , . C , , C, , , , , . , C,
, . C++, C++. C++ C++, C.
, C++. .
, .