Skip to content

Commit f9e2028

Browse files
authored
Merge branch 'master' into mb-ide
2 parents f223475 + d7d097b commit f9e2028

File tree

7 files changed

+483
-123
lines changed

7 files changed

+483
-123
lines changed

docs/error-messages/compiler-errors-1/TOC.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@
355355
## [Compiler Error C2276](compiler-error-c2276.md)
356356
## [Compiler Error C2277](compiler-error-c2277.md)
357357
## [Compiler Error C2279](compiler-error-c2279.md)
358+
## [Compiler Error C2280](compiler-error-c2280.md)
358359
## [Compiler Error C2283](compiler-error-c2283.md)
359360
## [Compiler Error C2285](compiler-error-c2285.md)
360361
## [Compiler Error C2286](compiler-error-c2286.md)
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
---
2+
title: "Compiler Error C2280 | Microsoft Docs"
3+
ms.custom: ""
4+
ms.date: "04/25/2017"
5+
ms.reviewer: ""
6+
ms.suite: ""
7+
ms.technology:
8+
- "devlang-cpp"
9+
ms.tgt_pltfrm: ""
10+
ms.topic: "article"
11+
f1_keywords:
12+
- "C2280"
13+
helpviewer_keywords:
14+
- "C2280"
15+
dev_langs:
16+
- "C++"
17+
ms.assetid: e6c5b1fb-2b9b-4554-8ff9-775eeb37161b
18+
caps.latest.revision: 8
19+
author: "corob-msft"
20+
ms.author: "corob"
21+
manager: "ghogen"
22+
translation.priority.ht:
23+
- "de-de"
24+
- "es-es"
25+
- "fr-fr"
26+
- "it-it"
27+
- "ja-jp"
28+
- "ko-kr"
29+
- "ru-ru"
30+
- "zh-cn"
31+
- "zh-tw"
32+
translation.priority.mt:
33+
- "cs-cz"
34+
- "pl-pl"
35+
- "pt-br"
36+
- "tr-tr"
37+
---
38+
# Compiler Error C2280
39+
40+
'*declaration*': attempting to reference a deleted function
41+
42+
The compiler detected an attempt to reference a `deleted` function. This error can be caused by a call to a member function that has been explicitly marked as `= deleted` in the source code. This error can also be caused by a call to an implicit special member function of a struct or class that is automatically declared and marked as `deleted` by the compiler. For more information about when the compiler automatically generates `default` or `deleted` special member functions, see [Special member functions](../../cpp/special-member-functions.md).
43+
44+
## Example: Explicitly deleted functions
45+
46+
A call to an explicitly `deleted` function causes this error. An explicitly `deleted` member function implies that the class or struct is intentionally designed to prevent its use, so to fix this issue, you should change your code to avoid it.
47+
48+
```cpp
49+
// C2280_explicit.cpp
50+
// compile with: cl /c /W4 C2280_explicit.cpp
51+
struct A {
52+
A();
53+
A(int) = delete;
54+
};
55+
56+
struct B {
57+
A a1;
58+
A a2 = A(3); // C2280, calls deleted A::A(int)
59+
// To fix, remove the call to A(int)
60+
};
61+
62+
void f() {
63+
B b; // calls implicit B::B(void)
64+
}
65+
```
66+
67+
## Example: Uninitialized data members
68+
69+
An uninitialized reference type data member or `const` data member causes the compiler to implicitly declare a `deleted` default constructor. To fix this issue, initialize the data member when it is declared.
70+
71+
```cpp
72+
// C2280_uninit.cpp
73+
// compile with: cl /c C2280_uninit.cpp
74+
struct A {
75+
const int i; // uninitialized const-qualified data
76+
// members or reference type data members cause
77+
// the implicit default constructor to be deleted.
78+
// To fix, initialize the value in the declaration:
79+
// const int i = 42;
80+
} a; // C2280
81+
```
82+
83+
## Example: Reference and const data members
84+
85+
A `const` or reference type data member causes the compiler to declare a `deleted` copy assignment operator. Once initialized, these members can't be assigned to. To fix this issue, we recommend you change your logic to remove the assignment operations that cause the error.
86+
87+
```cpp
88+
// C2280_ref.cpp
89+
// compile with: cl /c C2280_ref.cpp
90+
extern int k;
91+
struct A {
92+
A();
93+
int& ri = k; // a const or reference data member causes
94+
// implicit copy assignment operator to be deleted.
95+
};
96+
97+
void f() {
98+
A a1, a2;
99+
// To fix, consider removing this assignment.
100+
a2 = a1; // C2280
101+
}
102+
```
103+
104+
## Example: Movable deletes implicit copy
105+
106+
If a class declares a move constructor or move assignment operator, but does not explicitly declare a copy constructor, the compiler implicitly declares a copy constructor and defines it as `deleted`. Similarly, if a class declares a move constructor or move assignment operator, but does not explicitly declare a copy assignment operator, the compiler implicitly declares a copy assignment operator and defines it as `deleted`. To fix this issue, you must explicitly declare these members.
107+
108+
When you see error C2280 in connection with a `unique_ptr`, it is almost certainly because you are attempting to invoke its copy constructor, which is a `deleted` function. By design, a `unique_ptr` cannot be copied. Use a move constructor to transfer ownership instead.
109+
110+
```cpp
111+
// C2280_move.cpp
112+
// compile with: cl /c C2280_move.cpp
113+
class base
114+
{
115+
public:
116+
base();
117+
~base();
118+
base(base&&);
119+
// Move constructor causes copy constructor to be
120+
// implicitly declared as deleted. To fix this
121+
// issue, you can explicitly declare a copy constructor:
122+
// base(base&);
123+
// If you want the compiler default version, do this:
124+
// base(base&) = default;
125+
};
126+
127+
void copy(base *p)
128+
{
129+
base b{*p}; // C2280
130+
}
131+
```
132+
133+
## Example: Variant and volatile members
134+
135+
Versions of the compiler before Visual Studio 2015 Update 2 were non-conforming and generated default constructors and destructors for anonymous unions. These are now implicitly declared as `deleted`. Those versions also allowed non-conforming implicit definition of `default` copy and move constructors and `default` copy and move assignment operators in classes and structs that have `volatile` member variables. The compiler now considers these to have non-trivial constructors and assignment operators, and doesn't generate `default` implementations. When such a class is a member of a union, or an anonymous union inside of a class, the copy and move constructors and copy and move assignment operators of the union or class are implicitly defined as `deleted`. To fix this issue, you must explicitly declare the required special member functions.
136+
137+
```cpp
138+
// C2280_variant.cpp
139+
// compile with: cl /c C2280_variant.cpp
140+
struct A {
141+
A() = default;
142+
A(const A&);
143+
};
144+
145+
struct B {
146+
union {
147+
A a;
148+
int i;
149+
};
150+
// To fix this issue, declare the required
151+
// special member functions:
152+
// B();
153+
// B(const B& b);
154+
};
155+
156+
int main() {
157+
B b1;
158+
B b2(b1); // C2280
159+
}
160+
```
161+
162+
## Example: Indirect base members deleted
163+
164+
Versions of the compiler before Visual Studio 2015 Update 2 were non-conforming and allowed a derived class to call special member functions of indirectly-derived `private virtual` base classes. The compiler now issues compiler error C2280 when such a call is made.
165+
166+
In this example, class `top` indirectly derives from private virtual `base`. In conforming code, this makes the members of `base` inaccessible to `top`; an object of type `top` can't be default constructed or destroyed. To fix this issue in code that relied on the old compiler behavior, change the intermediate class to use `protected virtual` derivation, or change the `top` class to use direct derivation:
167+
168+
```cpp
169+
// C2280_indirect.cpp
170+
// compile with: cl /c C2280_indirect.cpp
171+
class base
172+
{
173+
protected:
174+
base();
175+
~base();
176+
};
177+
178+
class middle : private virtual base {};
179+
// Possible fix: Replace line above with:
180+
// class middle : protected virtual base {};
181+
class top : public virtual middle {}; // C4594, C4624
182+
// Another possible fix: use direct derivation:
183+
// class top : public virtual middle, private virtual base {};
184+
185+
void destroy(top *p)
186+
{
187+
delete p; // C2280
188+
}
189+
```
190+

docs/error-messages/compiler-errors-1/compiler-errors-c2200-through-c2299.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ f1_keywords:
2828
- "C2265"
2929
- "C2269"
3030
- "C2278"
31-
- "C2280"
3231
- "C2281"
3332
- "C2282"
3433
- "C2288"
@@ -54,7 +53,6 @@ helpviewer_keywords:
5453
- "C2265"
5554
- "C2269"
5655
- "C2278"
57-
- "C2280"
5856
- "C2281"
5957
- "C2282"
6058
- "C2288"
@@ -172,7 +170,7 @@ The articles in this part of the documentation contain information about a subse
172170
|[Compiler Error C2277](compiler-error-c2277.md)|'*function*': cannot take address of this member function|
173171
|Compiler Error C2278|Obsolete.|
174172
|[Compiler Error C2279](compiler-error-c2279.md)|exception specification cannot appear in a typedef declaration|
175-
|Compiler Error C2280|'*class*::*function*': attempting to reference a deleted function|
173+
|[Compiler Error C2280](compiler-error-c2280.md)|'*class*::*function*': attempting to reference a deleted function|
176174
|Compiler Error C2281|'*class*::*function*': a function can only be deleted on the first declaration|
177175
|Compiler Error C2282|'*function1*' cannot override '*function2*'|
178176
|[Compiler Error C2283](compiler-error-c2283.md)|'*identifer*': pure specifier or abstract override specifier not allowed on unnamed class/struct|

docs/error-messages/compiler-warnings/TOC.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@
297297
## [Compiler Warning (level 1) C4461](compiler-warning-level-1-c4461.md)
298298
## [Compiler Warning (level 1) C4462](compiler-warning-level-1-c4462.md)
299299
## [Compiler Warning (level 1) C4470](compiler-warning-level-1-c4470.md)
300+
## [Compiler Warning (level 4) C4471](compiler-warning-level-4-c4471.md)
300301
## [Compiler Warning (level 4) C4481](compiler-warning-level-4-c4481.md)
301302
## [Compiler Warning C4484](compiler-warning-c4484.md)
302303
## [Compiler Warning C4485](compiler-warning-c4485.md)
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
---
2+
title: "Compiler Warning (level 4) C4471 | Microsoft Docs"
3+
ms.custom: ""
4+
ms.date: "04/24/2017"
5+
ms.reviewer: ""
6+
ms.suite: ""
7+
ms.technology:
8+
- "devlang-cpp"
9+
ms.tgt_pltfrm: ""
10+
ms.topic: "error-reference"
11+
f1_keywords:
12+
- "C4471"
13+
dev_langs:
14+
- "C++"
15+
helpviewer_keywords:
16+
- "C4471"
17+
ms.assetid: ccfd8bd5-bc1b-4be7-a6ea-0e3a7add6607
18+
caps.latest.revision: 1
19+
author: "corob-msft"
20+
ms.author: "corob"
21+
manager: "ghogen"
22+
translation.priority.ht:
23+
- "cs-cz"
24+
- "de-de"
25+
- "es-es"
26+
- "fr-fr"
27+
- "it-it"
28+
- "ja-jp"
29+
- "ko-kr"
30+
- "pl-pl"
31+
- "pt-br"
32+
- "ru-ru"
33+
- "tr-tr"
34+
- "zh-cn"
35+
- "zh-tw"
36+
---
37+
# Compiler Warning (level 4) C4471
38+
'*enumeration*': a forward declaration of an unscoped enumeration must have an underlying type (int assumed)
39+
40+
A forward declaration of an unscoped enumeration was found without a specifier for the underlying type. By default, Visual C++ assumes `int` is the underlying type for an enumeration. This can cause issues if a different type is used in the enumeration definition, for example, if a different explicit type is specified, or if a different type is implicitly set by an initializer. You may also have portability issues; other compilers do not assume `int` is the underlying type of an enumeration.
41+
42+
This warning is off by default; you can use /Wall or /w*N*4471 to enable it on the command line, or use #pragma [warning](../../preprocessor/warning.md) in your source file.
43+
44+
In some cases, this warning is spurious. If a forward declaration for an enumeration appears after the definition, this warning may fire. For example, this code is valid, even though it may cause C4471:
45+
46+
```cpp
47+
// C4471a.cpp
48+
// Compile with: cl /c /w14471 C4471a.cpp
49+
enum Example { item = 0x80000000UL };
50+
enum Example; // Spurious C4471
51+
// ...
52+
```
53+
54+
## Example
55+
In general, it's safe to use the full definition for an unscoped enumeration instead of a forward declaration. You can put the definition in a header file and include it in source files that refer to it. This works in code written for C++98 and later. We recommend this solution for portability and ease of maintenance.
56+
57+
```cpp
58+
// C4471b.cpp
59+
// Compile with: cl /c /w14471 C4471b.cpp
60+
enum Example; // C4471
61+
// To fix, replace the line above with the enumeration definition:
62+
// enum Example { item = 0x80000000UL };
63+
// ...
64+
```
65+
66+
## Example
67+
In C++11, you can add an explicit type to an unscoped enumeration and to its forward declaration. We recommend this solution only if complex header inclusion logic prevents use of the definition instead of a forward declaration. This solution can lead to a maintenance issue: if you change the underlying type used for the enumeration definition, you must also change all of the forward declarations to match, or you may have silent errors in your code. You can put the forward declaration into a header file to minimize this issue.
68+
69+
```cpp
70+
// C4471c.cpp
71+
// Client code for enumeration defined in C4471d.cpp
72+
// Compile with: cl /c /w14471 C4471c.cpp C4471d.cpp
73+
enum Example; // C4471, int assumed
74+
// To fix, replace the lines above with the forward declarations:
75+
// enum Example : unsigned;
76+
// ...
77+
```
78+
79+
```cpp
80+
// C4471d.cpp
81+
// Definition for enumeration used in C4471c.cpp
82+
// Compile with: cl /c /w14471 C4471c.cpp C4471d.cpp
83+
enum Example : unsigned { item = 0x80000000 }; // explicit type
84+
// ...
85+
```
86+
87+
If you specify an explicit type for an enumeration, we recommend you also enable warning [C4369](compiler-warning-level-1-C4369.md), which is on by default. This identifies cases where an enumeration item requires a different type than the explicitly specified type.
88+
89+
## Example
90+
You can change your code to use a scoped enum, a feature that is new in C++11. Both the definition and any client code that uses the enumeration type must be changed to use a scoped enum. We recommend you use a scoped enum if you have issues with namespace pollution, as the names of defined enumeration items are limited to the scope of the enum. Another feature of a scoped enum is that its members can't be implicitly converted to another integral or enumeration type, which can be a source of subtle bugs.
91+
92+
```cpp
93+
// C4471e.cpp
94+
// Client code for scoped enumeration defined in C4471f.cpp
95+
// Compile with: cl /c /w14471 C4471e.cpp C4471f.cpp
96+
enum Example; // C4471
97+
// To fix, replace the line above with the forward declaration:
98+
// enum class Example;
99+
// ...
100+
```
101+
102+
```cpp
103+
// C4471f.cpp
104+
// Definition for scoped enumeration used in C4471e.cpp
105+
// Compile with: cl /c /w14471 C4471e.cpp C4471f.cpp
106+
enum class Example { item = 0 };
107+
// ...
108+
```
109+

0 commit comments

Comments
 (0)