Skip to content

Commit 2425664

Browse files
author
Colin Robertson
authored
Prepare for new ptr-to-member error (MicrosoftDocs#3503)
1 parent 660abf4 commit 2425664

7 files changed

+121
-95
lines changed
Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,42 @@
11
---
2-
description: "Learn more about: /vmb, /vmg (Representation Method)"
2+
description: "Learn more about: /vmb, /vmg (Representation method)"
33
title: "/vmb, /vmg (Representation Method)"
4-
ms.date: "11/04/2016"
4+
ms.date: 04/12/2021
55
f1_keywords: ["/vmb", "/vmg"]
66
helpviewer_keywords: ["vmb compiler option [C++]", "-vmg compiler option [C++]", "vmg compiler option [C++]", "-vmb compiler option [C++]", "/vmb compiler option [C++]", "representation method compiler options [C++]", "/vmg compiler option [C++]"]
7-
ms.assetid: ecdb391c-7dab-40b1-916b-673d10889fd4
87
---
9-
# /vmb, /vmg (Representation Method)
8+
# `/vmb`, `/vmg` (Representation method)
109

1110
Select the method that the compiler uses to represent pointers to class members.
1211

13-
Use **/vmb** if you always define a class before you declare a pointer to a member of the class.
12+
## Syntax
1413

15-
Use **/vmg** to declare a pointer to a member of a class before defining the class. This need can arise if you define members in two different classes that reference each other. For such mutually referencing classes, one class must be referenced before it is defined.
14+
> **`/vmb`**\
15+
> **`/vmg`**
1616
17-
## Syntax
17+
### Options
1818

19-
```
20-
/vmb
21-
/vmg
22-
```
19+
**`/vmb`** is the compiler's default behavior. Its behavior is the same as `#pragma pointers_to_members(best_case)`. It doesn't require or ensure complete types. For complete types, it uses the best representation among single, multiple, or virtual inheritance based the inheritance of the class type. For incomplete types, it uses the largest, most general representation.
20+
21+
**`/vmg`** lets you specify compiler behavior in combination with [`/vmm`, `/vms`, `/vmv` (General purpose representation)](./vmm-vms-vmv-general-purpose-representation.md) to declare a pointer to a member of a class before defining the class. This need can arise if you define members in two different classes that reference each other. For such mutually referencing classes, one class must be referenced before it's defined.
2322

2423
## Remarks
2524

26-
You can also use [pointers_to_members](../../preprocessor/pointers-to-members.md) or [Inheritance Keywords](../../cpp/inheritance-keywords.md) in your code to specify a pointer representation.
25+
You can also use [`#pragma pointers_to_members`](../../preprocessor/pointers-to-members.md) or [Inheritance keywords](../../cpp/inheritance-keywords.md) in your code to specify a pointer representation.
2726

2827
### To set this compiler option in the Visual Studio development environment
2928

3029
1. Open the project's **Property Pages** dialog box. For details, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md).
3130

32-
1. Click the **C/C++** folder.
33-
34-
1. Click the **Command Line** property page.
31+
1. Select the **Configuration Properties** > **C/C++** > **Command Line** property page.
3532

36-
1. Type the compiler option in the **Additional Options** box.
33+
1. Enter the compiler option in the **Additional Options** box.
3734

3835
### To set this compiler option programmatically
3936

4037
- See <xref:Microsoft.VisualStudio.VCProjectEngine.VCCLCompilerTool.AdditionalOptions%2A>.
4138

4239
## See also
4340

44-
[MSVC Compiler Options](compiler-options.md)<br/>
45-
[MSVC Compiler Command-Line Syntax](compiler-command-line-syntax.md)
41+
[MSVC compiler options](compiler-options.md)<br/>
42+
[MSVC compiler command-line syntax](compiler-command-line-syntax.md)
Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,66 @@
11
---
22
description: "Learn more about: /vmm, /vms, /vmv (General Purpose Representation)"
3-
title: "/vmm, -vms, -vmv (General Purpose Representation)"
4-
ms.date: "11/04/2016"
3+
title: "/vmm, /vms, /vmv (General Purpose Representation)"
4+
ms.date: 04/12/2021
55
f1_keywords: ["/vms", "/vmm", "/vmv"]
66
helpviewer_keywords: ["Virtual Inheritance compiler option", "general purpose representation compiler options", "vms compiler option [C++]", "vmm compiler option [C++]", "/vmm compiler option [C++]", "-vmm compiler option [C++]", "-vms compiler option [C++]", "/vms compiler option [C++]", "vmv compiler option [C++]", "/vmv compiler option [C++]", "Single Inheritance compiler option", "-vmv compiler option [C++]"]
7-
ms.assetid: 0fcd7ae0-3031-4c62-a2a8-e154c8685dae
87
---
9-
# /vmm, /vms, /vmv (General Purpose Representation)
8+
# `/vmm`, `/vms`, `/vmv` (General Purpose Representation)
109

11-
Used when [/vmb, /vmg (Representation Method)](vmb-vmg-representation-method.md) is selected as the [representation method](vmb-vmg-representation-method.md). These options indicate the inheritance model of the not-yet-encountered class definition.
10+
Used when [`/vmg`](vmb-vmg-representation-method.md) is selected as the [representation method](vmb-vmg-representation-method.md). These options indicate the inheritance model of the not-yet-encountered class definition.
1211

1312
## Syntax
1413

15-
```
16-
/vmm
17-
/vms
18-
/vmv
19-
```
14+
> **`/vmm`**\
15+
> **`/vms`**\
16+
> **`/vmv`**
2017
21-
## Remarks
18+
### Options
19+
20+
**`/vmm`**\
21+
Specifies the most general representation of a pointer to a member of a class as one that uses multiple inheritance.
22+
23+
The corresponding [inheritance keyword](../../cpp/inheritance-keywords.md) and argument to [`#pragma pointers_to_members`](../../preprocessor/pointers-to-members.md) is **`multiple_inheritance`**.
24+
25+
This representation is larger than the one required for single inheritance.
26+
27+
If you use **`/vmm`** and declare a pointer to member of a class that has a virtual inheritance model, the compiler generates an error.
28+
29+
**`/vms`**\
30+
Specifies the most general representation of a pointer to a member of a class as one that uses either no inheritance or single inheritance.The corresponding [inheritance keyword](../../cpp/inheritance-keywords.md) and argument to [`#pragma pointers_to_members`](../../preprocessor/pointers-to-members.md) is **`single_inheritance`**.
2231

23-
The options are described in the following table.
32+
This option generates the smallest possible representation of a pointer to a member of a class.
33+
34+
If you use **`/vms`** and declare a pointer to member of a class that has a multiple or virtual inheritance model, the compiler generates an error.
35+
36+
**`/vmv`**\
37+
Specifies the most general representation of a pointer to a member of a class as one that uses virtual inheritance. This pointer representation never causes an error and is the default.
38+
39+
The corresponding [inheritance keyword](../../cpp/inheritance-keywords.md) and argument to [`#pragma pointers_to_members`](../../preprocessor/pointers-to-members.md) is **`virtual_inheritance`**.
40+
41+
This option requires a larger pointer and more code to interpret the pointer than the other options.
42+
43+
## Remarks
2444

25-
|Option|Description|
26-
|------------|-----------------|
27-
|**/vmm**|Specifies the most general representation of a pointer to a member of a class to be one that uses multiple inheritance.<br /><br /> The corresponding [inheritance keyword](../../cpp/inheritance-keywords.md) and argument to [#pragma pointers_to_members](../../preprocessor/pointers-to-members.md) is **multiple_inheritance**.<br /><br /> This representation is larger than that required for single inheritance.<br /><br /> If the inheritance model of a class definition for which a pointer to a member is declared is virtual, the compiler generates an error.|
28-
|**/vms**|Specifies the most general representation of a pointer to a member of a class to be one that uses either no inheritance or single inheritance.<br /><br /> The corresponding [inheritance keyword](../../cpp/inheritance-keywords.md) and argument to [#pragma pointers_to_members](../../preprocessor/pointers-to-members.md) is **single_inheritance**.<br /><br /> This is the smallest possible representation of a pointer to a member of a class.<br /><br /> If the inheritance model of a class definition for which a pointer to a member is declared is multiple or virtual, the compiler generates an error.|
29-
|**/vmv**|Specifies the most general representation of a pointer to a member of a class to be one that uses virtual inheritance. It never causes an error and is the default.<br /><br /> The corresponding [inheritance keyword](../../cpp/inheritance-keywords.md) and argument to [#pragma pointers_to_members](../../preprocessor/pointers-to-members.md) is **virtual_inheritance**.<br /><br /> This option requires a larger pointer and additional code to interpret the pointer than the other options.|
45+
In Visual Studio 2019 and earlier versions, Microsoft uses different representations (of different sizes) for pointer-to-member types. Pointers to members of classes that have no inheritance or single inheritance have the smallest representation. Pointers to members of classes that have multiple inheritance are larger. Pointers to members of classes that have virtual inheritance are the largest. When no representation model is specified to the compiler, it defaults to using the largest, most general representation.
3046

31-
When you specify one of these inheritance-model options, that model is used for all pointers to class members, regardless of their inheritance type or whether the pointer is declared before or after the class. Therefore, if you always use single-inheritance classes, you can reduce code size by compiling with **/vms**; however, if you want to use the most general case (at the expense of the largest data representation), compile with **/vmv**.
47+
When you specify one of these inheritance-model options, that model gets used for all pointers to class members, no matter their inheritance type or whether you declare the pointer before or after the class. If you always use single-inheritance classes, you can reduce code size by compiling with **`/vms`**. However, if you want to use the most general case (at the expense of the largest data representation), compile with **`/vmv`**.
3248

3349
### To set this compiler option in the Visual Studio development environment
3450

3551
1. Open the project's **Property Pages** dialog box. For details, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md).
3652

37-
1. Click the **C/C++** folder.
53+
1. Select the **Configuration Properties** > **C/C++** > **Command Line** property page.
3854

39-
1. Click the **Command Line** property page.
55+
1. Enter the compiler option in the **Additional Options** box.
4056

41-
1. Type the compiler option in the **Additional Options** box.
4257

4358
### To set this compiler option programmatically
4459

4560
- See <xref:Microsoft.VisualStudio.VCProjectEngine.VCCLCompilerTool.AdditionalOptions%2A>.
4661

4762
## See also
4863

49-
[/vmb, /vmg (Representation Method)](vmb-vmg-representation-method.md)<br/>
50-
[MSVC Compiler Options](compiler-options.md)<br/>
51-
[MSVC Compiler Command-Line Syntax](compiler-command-line-syntax.md)
64+
[`/vmb`, `/vmg` (Representation method)](vmb-vmg-representation-method.md)<br/>
65+
[MSVC compiler options](compiler-options.md)<br/>
66+
[MSVC compiler command-line syntax](compiler-command-line-syntax.md)

docs/cpp/inheritance-keywords.md

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,43 @@
11
---
22
description: "Learn more about: Inheritance Keywords"
3-
title: "Inheritance Keywords"
4-
ms.date: "11/04/2016"
3+
title: "Inheritance keywords"
4+
ms.date: 04/12/2021
55
f1_keywords: ["__multiple_inheritance", "__single_inheritance_cpp", "__virtual_inheritance_cpp", "__virtual_inheritance", "__multiple_inheritance_cpp", "__single_inheritance"]
66
helpviewer_keywords: ["__single_inheritance keyword [C++]", "declaring derived classes [C++]", "keywords [C++], inheritance keywords", "__multiple_inheritance keyword [C++]", "__virtual_inheritance keyword [C++]", "inheritance, declaring derived classes", "derived classes [C++], declaring", "inheritance, keywords"]
7-
ms.assetid: bb810f56-7720-4fea-b8b6-9499edd141df
87
---
9-
# Inheritance Keywords
8+
# Inheritance keywords
109

1110
**Microsoft Specific**
1211

13-
```
14-
class [__single_inheritance] class-name;
15-
class [__multiple_inheritance] class-name;
16-
class [__virtual_inheritance] class-name;
17-
```
12+
> **`class`** *`class-name`*\
13+
> **`class __single_inheritance`** *`class-name`*\
14+
> **`class __multiple_inheritance`** *`class-name`*\
15+
> **`class __virtual_inheritance`** *`class-name`*
1816
1917
where:
2018

21-
*class-name*<br/>
19+
*`class-name`*<br/>
2220
The name of the class being declared.
2321

24-
C++ allows you to declare a pointer to a class member prior to the definition of the class. For example:
22+
C++ allows you to declare a pointer to a class member before the definition of the class. For example:
2523

2624
```cpp
2725
class S;
2826
int S::*p;
2927
```
3028

31-
In the code above, `p` is declared to be a pointer to integer member of class S. However, `class S` has not yet been defined in this code; it has only been declared. When the compiler encounters such a pointer, it must make a generalized representation of the pointer. The size of the representation is dependent on the inheritance model specified. There are four ways to specify an inheritance model to the compiler:
32-
33-
- In the IDE under **Pointer-to-member representation**
29+
In the code above, `p` is declared to be a pointer to integer member of class S. However, `class S` hasn't been defined yet in this code; it's only been declared. When the compiler encounters such a pointer, it must make a generalized representation of the pointer. The size of the representation is dependent on the inheritance model specified. There are three ways to specify an inheritance model to the compiler:
3430

35-
- At the command line using the [/vmg](../build/reference/vmb-vmg-representation-method.md) switch
31+
- At the command line using the [`/vmg`](../build/reference/vmb-vmg-representation-method.md) switch
3632

37-
- Using the [pointers_to_members](../preprocessor/pointers-to-members.md) pragma
33+
- Using the [`pointers_to_members`](../preprocessor/pointers-to-members.md) pragma
3834

3935
- Using the inheritance keywords **`__single_inheritance`**, **`__multiple_inheritance`**, and **`__virtual_inheritance`**. This technique controls the inheritance model on a per-class basis.
4036

4137
> [!NOTE]
4238
> If you always declare a pointer to a member of a class after defining the class, you don't need to use any of these options.
4339
44-
Declaring a pointer to a member of a class prior to the class definition affects the size and speed of the resulting executable file. The more complex the inheritance used by a class, the greater the number of bytes required to represent a pointer to a member of the class and the larger the code required to interpret the pointer. Single inheritance is least complex, and virtual inheritance is most complex.
40+
If you declare a pointer to a class member before the class is defined, it can negatively affect the size and speed of the resulting executable file. The more complex the inheritance used by a class, the greater the number of bytes required to represent a pointer to a member of the class. And, the larger the code required to interpret the pointer. Single (or no) inheritance is least complex, and virtual inheritance is most complex. Pointers to members you declare before the class is defined always use the largest, most complex representation.
4541

4642
If the example above is changed to:
4743

@@ -50,12 +46,12 @@ class __single_inheritance S;
5046
int S::*p;
5147
```
5248
53-
regardless of command-line options or pragmas, pointers to members of `class S` will use the smallest possible representation.
49+
then no matter the command-line options or pragmas you specify, pointers to members of `class S` will use the smallest possible representation.
5450
5551
> [!NOTE]
5652
> The same forward declaration of a class pointer-to-member representation should occur in every translation unit that declares pointers to members of that class, and the declaration should occur before the pointers to members are declared.
5753
58-
For compatibility with previous versions, **`_single_inheritance`**, **`_multiple_inheritance`**, and **`_virtual_inheritance`** are synonyms for **`__single_inheritance`**, **`__multiple_inheritance`**, and **`__virtual_inheritance`** unless compiler option [/Za \(Disable language extensions)](../build/reference/za-ze-disable-language-extensions.md) is specified.
54+
For compatibility with previous versions, **`_single_inheritance`**, **`_multiple_inheritance`**, and **`_virtual_inheritance`** are synonyms for **`__single_inheritance`**, **`__multiple_inheritance`**, and **`__virtual_inheritance`** unless compiler option [`/Za` \(Disable language extensions)](../build/reference/za-ze-disable-language-extensions.md) is specified.
5955
6056
**END Microsoft Specific**
6157

docs/error-messages/compiler-warnings/compiler-warning-level-1-c4407.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11
---
22
description: "Learn more about: Compiler Warning (level 1) C4407"
33
title: "Compiler Warning (level 1) C4407"
4-
ms.date: "11/04/2016"
4+
ms.date: 04/13/2021
55
f1_keywords: ["C4407"]
66
helpviewer_keywords: ["C4407"]
7-
ms.assetid: 32bc2c21-363a-4bb8-b486-725faeaededc
87
---
98
# Compiler Warning (level 1) C4407
109

11-
cast between different pointer to member representations, compiler may generate incorrect code
10+
> cast between different pointer to member representations, compiler may generate incorrect code
1211
13-
An incorrect cast was detected.
12+
An incorrect cast between pointer-to-member types was detected.
13+
14+
## Remarks
1415

1516
C4407 can be generated because of compiler conformance work that was done in Visual Studio 2005. Pointer-to-member now requires a qualified name and the address-of operator (&).
1617

17-
C4407 can occur if you cast between a multiple inheritance pointer-to-member to a single inheritance pointer-to-member. Sometimes this can work, but sometimes it can’t because the single inheritance pointer-to-member representation doesn’t hold sufficient information. Compiling with the **/vmm** might help (for more information, see [/vmm, /vms, /vmv (General Purpose Representation)](../../build/reference/vmm-vms-vmv-general-purpose-representation.md)). You can also try rearranging your base classes; the compiler is detecting a loss of information in the conversion because a base class is at a non-zero offset from the derived.
18+
C4407 can occur if you cast between a multiple inheritance pointer-to-member to a single inheritance pointer-to-member. Sometimes this can work, but sometimes it can’t because the single inheritance pointer-to-member representation doesn’t hold sufficient information. Compiling with the **`/vmm`** might help. For more information, see [`/vmm`, `/vms`, `/vmv` (General purpose representation)](../../build/reference/vmm-vms-vmv-general-purpose-representation.md). You can also try rearranging your base classes; the compiler is detecting a loss of information in the conversion because a base class is at a non-zero offset from the derived.
19+
20+
## Example
1821

19-
The following sample generates C4407:
22+
The following sample generates C4407 and shows how to fix it:
2023

2124
```cpp
2225
// C4407.cpp

0 commit comments

Comments
 (0)