Recentemente,
fui lembrado por que
considero uma péssima idéia fornecer C ++ para iniciantes. Essa é uma
péssima idéia , porque em C ++ uma bagunça real é uma bagunça linda, mas pervertida, trágica e surpreendente. Apesar do estado atual da comunidade, este artigo não é direcionado contra
o C ++
moderno . Em vez disso, ela continua parcialmente o
artigo de Simon Brand,
“A inicialização em C ++ é uma loucura” e, em parte, é uma mensagem para todos os estudantes que desejam iniciar seus estudos olhando para o abismo.
Objeções típicas dos alunos quando são informadas sobre a aprendizagem C:
- "Alguém mais está usando?"
- "Isso é estúpido."
- "Por que estamos aprendendo C?"
- “Precisamos aprender algo melhor, por exemplo, C ++” ( risos )
Parece que muitos estudantes pensam que aprender C realmente não importa (do autor: não é) e deve começar com C ++. Vejamos apenas uma das razões pelas quais essa é uma proposta absurda:
criar uma porra de variável . No artigo original, Simon Brand sugeriu que o leitor já estava familiarizado com as esquisitices de inicialização nas versões anteriores ao C ++ 11. Aqui, olhamos para alguns deles e vamos um pouco mais longe.
Deixe-me começar explicando que, neste artigo, minha opinião pessoal, e
não a posição oficial da Universidade de Drexel, onde ensino no Departamento de Engenharia Elétrica e de Computação. Minhas palestras são geralmente incluídas no curso de um programa de engenharia, em vez de ciência da computação, ou seja, elas se relacionam mais à programação de sistemas e sistemas embarcados.
Resumo em um GIF
u / AlexAlabuzhev no Reddit conseguiu recontar este artigo inteiro em um gif. (Eu acho que este é o trabalho original de
Timur Dumler )
Não tenho nada contra o C ++, mas há muito de que você não precisa em um estágio inicial.
Isso é tudo. Vá para casa. Dê um passeio com o cachorro. Lave a roupa. Ligue para a mãe e diga que a ama. Experimente uma nova receita. Nada para ler aqui pessoal. De fato, pense em quão mal os engenheiros (ou seja, eu) são capazes de transmitir seus pensamentos ...
Tudo, eu convenci como pude!
Então, você ainda está aqui? Soldado de verdade. Se eu pudesse, daria uma medalha a você! E delicioso leite com chocolate!
Agora, de volta à nossa habitual ... programação.Inicialização em C
Entrada
Primeiro, considere a
inicialização em C , porque é semelhante ao C ++ por motivos de compatibilidade. Será bem rápido, porque C é muito chato e simples (
ahem ). Todo iniciante aprende essa inicialização de cor, porque em C funciona de maneira diferente do que em muitas novas linguagens estaticamente tipadas. Há uma inicialização padrão para valores aceitáveis ou um erro de compilação é gerado.
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++. .
, .