|
1 | 1 | ---
|
2 | 2 | description: "Learn more about: Compiler Warning (level 1) C4251"
|
3 | 3 | title: "Compiler Warning (level 1) C4251"
|
4 |
| -ms.date: 02/22/2022 |
| 4 | +ms.date: 12/01/2023 |
5 | 5 | f1_keywords: ["C4251"]
|
6 | 6 | helpviewer_keywords: ["C4251"]
|
7 |
| -ms.assetid: a9992038-f0c2-4fc4-a9be-4509442cbc1e |
8 | 7 | ---
|
9 | 8 | # Compiler Warning (level 1) C4251
|
10 | 9 |
|
11 | 10 | > '*type*' : class '*type1*' needs to have dll-interface to be used by clients of class '*type2*'
|
12 | 11 |
|
13 | 12 | ## Remarks
|
14 | 13 |
|
| 14 | +This warning happens if a class is marked with `__declspec(dllexport)` or `__declspec(dllimport)` and a nonstatic data member that is a member of the class or a member of one of its base classes, has a type that is a class type that isn't marked with `__declspec(dllexport)` or `__declspec(dllimport)`. See [Example](#example). |
| 15 | + |
15 | 16 | To minimize the possibility of data corruption when exporting a class declared as [`__declspec(dllexport)`](../../cpp/dllexport-dllimport.md), ensure that:
|
16 | 17 |
|
17 | 18 | - All your static data is accessed through functions that are exported from the DLL.
|
18 |
| - |
19 | 19 | - No inlined methods of your class can modify static data.
|
20 |
| - |
21 | 20 | - No inlined methods of your class use CRT functions or other library functions that use static data. For more information, see [Potential errors passing CRT objects across DLL boundaries](../../c-runtime-library/potential-errors-passing-crt-objects-across-dll-boundaries.md).
|
22 |
| - |
23 | 21 | - No methods of your class (whether inlined or not) can use types where the instantiation in the EXE and DLL have static data differences.
|
24 | 22 |
|
25 |
| -You can avoid issues when exporting a class from a DLL: Define your class to have virtual functions, a virtual destructor, and functions to instantiate and delete objects of the type. You can then just call virtual functions on the type. |
| 23 | +You can avoid issues when exporting a class from a DLL by: |
26 | 24 |
|
27 |
| -C4251 can be ignored if your class is derived from a type in the C++ Standard Library, you're compiling a debug release (**`/MTd`**), and where the compiler error message refers to `_Container_base`. |
| 25 | +- Defining your class to have virtual functions. |
| 26 | +- Defining a virtual destructor. |
| 27 | +- Defining functions to instantiate and delete instances of the type. |
28 | 28 |
|
29 |
| -## Example |
| 29 | +You can ignore C4251 if your class is derived from a type in the C++ Standard Library, you're compiling a debug release (**`/MTd`**), and the compiler error message refers to `_Container_base`. |
| 30 | + |
| 31 | +Think carefully about adding `__declspec(dllexport)` or `__declspec(dllimport)` to a class because it's almost always not the right choice and it can make maintenance more difficult because it makes changing implementation details harder. |
30 | 32 |
|
31 |
| -This sample exports a specialized class `VecWrapper` derived from `std::vector`. |
| 33 | +## Example |
32 | 34 |
|
33 | 35 | ```cpp
|
34 | 36 | // C4251.cpp
|
35 |
| -// compile with: /EHsc /MTd /W2 /c |
| 37 | +// Compile with /std:c++20 /EHsc /W2 /c C4251.cpp |
| 38 | +#include <vector> |
| 39 | + |
| 40 | +class __declspec(dllexport) X |
| 41 | +{ |
| 42 | +public: |
| 43 | + X(); |
| 44 | + ~X(); |
| 45 | + |
| 46 | + void do_something(); |
| 47 | + |
| 48 | +private: |
| 49 | + void do_something_else(); |
| 50 | + std::vector<int> data; // warning c4251 |
| 51 | +}; |
| 52 | +``` |
| 53 | + |
| 54 | +To fix this warning, don't mark the class with `__declspec(dllexport)` or `__declspec(dllimport)`. Instead, only mark the methods that are used directly by a client. For example: |
| 55 | + |
| 56 | +```cpp |
| 57 | +// C4251_fixed.cpp |
| 58 | +// Compile with /std:c++20 /EHsc /W2 /c C4251-fixed.cpp |
36 | 59 | #include <vector>
|
37 |
| -using namespace std; |
38 |
| -class Node; |
39 |
| -class __declspec(dllexport) VecWrapper : vector<Node *> {}; // C4251 |
| 60 | + |
| 61 | +class X |
| 62 | +{ |
| 63 | +public: |
| 64 | + __declspec(dllexport) X(); |
| 65 | + __declspec(dllexport) ~X(); |
| 66 | + |
| 67 | + __declspec(dllexport) void do_something(); |
| 68 | + |
| 69 | +private: |
| 70 | + void do_something_else(); |
| 71 | + std::vector<int> data; |
| 72 | +}; |
40 | 73 | ```
|
0 commit comments