Skip to content

Commit eb10b57

Browse files
authored
Merge pull request #5156 from MicrosoftDocs/FromPublicMasterBranch
Confirm merge from FromPublicMasterBranch to main to sync with https://github.com/MicrosoftDocs/cpp-docs (branch main)
2 parents 00336ea + 8e05170 commit eb10b57

File tree

5 files changed

+107
-77
lines changed

5 files changed

+107
-77
lines changed

docs/c-runtime-library/reference/vsnprintf-vsnprintf-vsnprintf-l-vsnwprintf-vsnwprintf-l.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ See [Behavior summary](#behavior-summary) for details.
125125

126126
Each of these functions takes a pointer to an argument list, then formats the data, and writes up to *`count`* characters to the memory pointed to by *`buffer`*. The **`vsnprintf`** function always writes a null terminator, even if it truncates the output. When you use **`_vsnprintf`** and **`_vsnwprintf`**, the buffer is null-terminated only if there's room at the end (that is, if the number of characters to write is less than *`count`*).
127127

128-
Beginning with the UCRT in Visual Studio 2015 and Windows 10, **`vsnprintf`** is no longer identical to **`_vsnprintf`**. The **`vsnprintf`** function conforms to the C99 standard; **`_vnsprintf`** is kept for backward compatibility with older code. The difference is that if you run out of buffer, `vsnprintf` null-terminates the end of the buffer and returns the number of characters that would have been required, while `_vsnprintf` doesn't null-terminate the buffer and returns -1. Also, `_vsnprintf()` includes one more character in the output because it doesn't null-terminate the buffer.
128+
Beginning with the UCRT in Visual Studio 2015 and Windows 10, **`vsnprintf`** is no longer identical to **`_vsnprintf`**. The **`vsnprintf`** function conforms to the C99 standard; **`_vsnprintf`** is kept for backward compatibility with older code. The difference is that if you run out of buffer, `vsnprintf` null-terminates the end of the buffer and returns the number of characters that would have been required, while `_vsnprintf` doesn't null-terminate the buffer and returns -1. Also, `_vsnprintf()` includes one more character in the output because it doesn't null-terminate the buffer.
129129

130130
> [!IMPORTANT]
131131
> To prevent certain kinds of security risks, ensure that *`format`* isn't a user-defined string. For more information, see [Avoiding buffer overruns](/windows/win32/SecBP/avoiding-buffer-overruns).

docs/cpp/inline-functions-cpp.md

Lines changed: 69 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -20,35 +20,38 @@ A function defined in the body of a class declaration is implicitly an inline fu
2020
In the following class declaration, the `Account` constructor is an inline function because it is defined in the body of the class declaration. The member functions `GetBalance`, `Deposit`, and `Withdraw` are specified `inline` in their definitions. The `inline` keyword is optional in the function declarations in the class declaration.
2121

2222
```cpp
23-
// Inline_Member_Functions.cpp
23+
// account.h
2424
class Account
2525
{
2626
public:
27-
Account(double initial_balance) { balance = initial_balance; }
28-
double GetBalance();
29-
double Deposit( double Amount );
30-
double Withdraw( double Amount );
27+
Account(double initial_balance)
28+
{
29+
balance = initial_balance;
30+
}
31+
32+
double GetBalance() const;
33+
double Deposit(double amount);
34+
double Withdraw(double amount);
35+
3136
private:
3237
double balance;
3338
};
3439

35-
inline double Account::GetBalance()
40+
inline double Account::GetBalance() const
3641
{
3742
return balance;
3843
}
3944

40-
inline double Account::Deposit( double Amount )
41-
{
42-
return ( balance += Amount );
43-
}
44-
45-
inline double Account::Withdraw( double Amount )
45+
inline double Account::Deposit(double amount)
4646
{
47-
return ( balance -= Amount );
47+
balance += amount;
48+
return balance;
4849
}
4950

50-
int main()
51+
inline double Account::Withdraw(double amount)
5152
{
53+
balance -= amount;
54+
return balance;
5255
}
5356
```
5457
@@ -90,10 +93,9 @@ Use the [`/Ob`](../build/reference/ob-inline-function-expansion.md) compiler opt
9093
```cpp
9194
// inline_keyword1.cpp
9295
// compile with: /c
93-
inline int max( int a , int b ) {
94-
if( a > b )
95-
return a;
96-
return b;
96+
inline int max(int a, int b)
97+
{
98+
return a < b ? b : a;
9799
}
98100
```
99101

@@ -105,13 +107,14 @@ A class's member functions can be declared inline, either by using the **`inline
105107
// inline_keyword2.cpp
106108
// compile with: /EHsc /c
107109
#include <iostream>
108-
using namespace std;
109110

110-
class MyClass {
111+
class MyClass
112+
{
111113
public:
112-
void print() { cout << i << ' '; } // Implicitly inline
114+
void print() { std::cout << i; } // Implicitly inline
115+
113116
private:
114-
int i;
117+
int i;
115118
};
116119
```
117120

@@ -152,13 +155,15 @@ A `Point` class can be defined as follows:
152155

153156
```cpp
154157
// when_to_use_inline_functions.cpp
158+
// compile with: /c
155159
class Point
156160
{
157161
public:
158-
// Define "accessor" functions as
159-
// reference types.
162+
// Define "accessor" functions
163+
// as reference types.
160164
unsigned& x();
161165
unsigned& y();
166+
162167
private:
163168
unsigned _x;
164169
unsigned _y;
@@ -168,13 +173,11 @@ inline unsigned& Point::x()
168173
{
169174
return _x;
170175
}
176+
171177
inline unsigned& Point::y()
172178
{
173179
return _y;
174180
}
175-
int main()
176-
{
177-
}
178181
```
179182

180183
Assuming coordinate manipulation is a relatively common operation in a client of such a class, specifying the two accessor functions (`x` and `y` in the preceding example) as **`inline`** typically saves the overhead on:
@@ -193,7 +196,9 @@ A macro has some things in common with an `inline` function. But there are impor
193196
```cpp
194197
#include <iostream>
195198

196-
#define mult(a, b) a * b
199+
#define mult1(a, b) a * b
200+
#define mult2(a, b) (a) * (b)
201+
#define mult3(a, b) ((a) * (b))
197202

198203
inline int multiply(int a, int b)
199204
{
@@ -202,40 +207,67 @@ inline int multiply(int a, int b)
202207

203208
int main()
204209
{
205-
std::cout << mult(5 + 5, 5 + 5) << std::endl; // outputs 35
206-
std::cout << multiply(5 + 5, 5 + 5) << std::endl; // outputs 100
210+
std::cout << (48 / mult1(2 + 2, 3 + 3)) << std::endl; // outputs 33
211+
std::cout << (48 / mult2(2 + 2, 3 + 3)) << std::endl; // outputs 72
212+
std::cout << (48 / mult3(2 + 2, 3 + 3)) << std::endl; // outputs 2
213+
std::cout << (48 / multiply(2 + 2, 3 + 3)) << std::endl; // outputs 2
207214

208-
std::cout << mult(2, 2.2) << std::endl>>; // no warning
215+
std::cout << mult3(2, 2.2) << std::endl; // no warning
209216
std::cout << multiply(2, 2.2); // Warning C4244 'argument': conversion from 'double' to 'int', possible loss of data
210217
}
211218
```
212219
213220
```Output
214-
35
215-
100
221+
33
222+
72
223+
2
224+
2
216225
4.4
217226
4
218227
```
219228

220229
Here are some of the differences between the macro and the inline function:
221230

222231
- Macros are always expanded inline. However, an inline function is only inlined when the compiler determines it is the optimal thing to do.
223-
- The macro may result in unexpected behavior. For example, the macro `mult(5+5,5+5)` expands to `5 + 5 * 5 + 5` resulting in 35, whereas the function evaluates `10 * 10`. You could address that by defining the macro as #define `mult(a, b) ((a)*(b))`.
232+
- The macro may result in unexpected behavior, which can lead to subtle bugs. For example, the expression `mult1(2 + 2, 3 + 3)` expands to `2 + 2 * 3 + 3` which evaluates to 11, but the expected result is 24. A seemingly valid fix is to add parentheses around both arguments of the function macro, resulting in `#define mult2(a, b) (a) * (b)`, which will solve the issue at hand but can still cause surprising behavior when part of a larger expression. That was demonstrated in the preceding example, and the problem could be addressed by defining the macro as such `#define mult3(a, b) ((a) * (b))`.
224233
- An inline function is subject to semantic processing by the compiler, whereas the preprocessor expands macros without that same benefit. Macros aren't type-safe, whereas functions are.
225234
- Expressions passed as arguments to inline functions are evaluated once. In some cases, expressions passed as arguments to macros can be evaluated more than once. For example, consider the following:
226235

227236
```cpp
237+
#include <iostream>
238+
228239
#define sqr(a) ((a) * (a))
229240

241+
int increment(int& number)
242+
{
243+
return number++;
244+
}
245+
246+
inline int square(int a)
247+
{
248+
return a * a;
249+
}
250+
230251
int main()
231252
{
232253
int c = 5;
233-
std::cout << sqr(c++) << std::endl; // outputs 25
234-
std::cout << c << std::endl; // outputs 7!
254+
std::cout << sqr(increment(c)) << std::endl; // outputs 30
255+
std::cout << c << std::endl; // outputs 7
256+
257+
c = 5;
258+
std::cout << square(increment(c)) << std::endl; // outputs 25
259+
std::cout << c; // outputs 6
235260
}
236261
```
237262
238-
In this example, the expression `c++` is evaluated twice; once for each occurrence of `a` in the macro expansion. Instead, if `sqr` were an inline function, the expression `c++` would be evaluated only once.
263+
```Output
264+
30
265+
7
266+
25
267+
6
268+
```
269+
270+
In this example, the function `increment` is called twice as the expression `sqr(increment(c))` expands to `((increment(c)) * (increment(c)))`. This caused the second invocation of `increment` to return 6, hence the expression evaluates to 30. Any expression that contains side effects may affect the result when used in a macro, examine the fully expanded macro to check if the behavior is intended. Instead, if the inline function `square` was used, the function `increment` would only be called once and the correct result of 25 will be obtained.
239271

240272
## See also
241273

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,63 @@
11
---
22
description: "Learn more about: Compiler Error C2385"
33
title: "Compiler Error C2385"
4-
ms.date: "11/04/2016"
4+
ms.date: "1/19/2024"
55
f1_keywords: ["C2385"]
66
helpviewer_keywords: ["C2385"]
7-
ms.assetid: 6d3dd1f2-e56d-49d7-865c-6a9acdb17417
87
---
98
# Compiler Error C2385
109

11-
ambiguous access of 'member'
10+
> ambiguous access of 'member'
1211
13-
The member can derive from more than one object (it is inherited from more than one object). To resolve this error,
12+
A member is inherited from more than one base type, making unqualified access to that member ambiguous. To resolve this error:
1413

15-
- Make the member unambiguous by providing a cast.
16-
17-
- Rename the ambiguous members in the base classes.
14+
- Explicitly qualify access to the member.
15+
- Cast the object to the base class containing the member before accessing the member.
16+
- Rename the ambiguous member in the base class.
17+
- Bring the member into scope.
1818

1919
## Example
2020

21-
The following sample generates C2385.
21+
The following sample generates C2385:
2222

2323
```cpp
2424
// C2385.cpp
25-
// C2385 expected
26-
#include <stdio.h>
27-
2825
struct A
2926
{
30-
void x(int i)
31-
{
32-
printf_s("\nIn A::x");
33-
}
27+
void func1(int i) {}
28+
void func2() {}
3429
};
3530

3631
struct B
3732
{
38-
void x(char c)
39-
{
40-
printf_s("\nIn B::x");
41-
}
33+
void func1(char c) {}
34+
void func2() {}
4235
};
4336

44-
// Delete the following line to resolve.
45-
struct C : A, B {}
46-
47-
// Uncomment the following 4 lines to resolve.
48-
// struct C : A, B
49-
// {
50-
// using B::x;
51-
// using A::x;
52-
// };
37+
struct C : A, B
38+
{
39+
// Uncomment the following lines to resolve the first 2 errors
40+
// The error below for the call to c.func2() will remain
41+
// using A::func1;
42+
// using B::func1;
43+
};
5344

5445
int main()
5546
{
56-
C aC;
57-
aC.x(100);
58-
aC.x('c');
59-
}
47+
C c;
6048

61-
struct C : A, B
62-
{
63-
using B::x;
64-
using A::x;
65-
};
49+
c.func1(123); // C2385
50+
c.func1('a'); // C2385
51+
c.func2(); // C2385
52+
53+
c.A::func2(); // OK because explicitly qualified
54+
c.B::func2(); // OK because explicitly qualified
55+
static_cast<A>(c).func2(); // OK because of the cast
56+
static_cast<B>(c).func2(); // OK because of the cast
57+
}
6658
```
59+
60+
You can resolve the ambiguous calls to `func1` by bringing both overloads into scope. However, this doesn't work for `func2` because `A::func2` and `B::func2` don't take arguments, so calling them can't be differentiated by their parameters. You can resolve the issue by:
61+
- Introduce the one you want to use into scope
62+
- Explicitly qualify the call with the base type
63+
- Cast the object before calling the function.

docs/intrinsics/rdtsc.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,5 @@ int main()
6262

6363
## See also
6464

65+
[__rdtscp](../intrinsics/rdtscp.md)\
6566
[Compiler intrinsics](../intrinsics/compiler-intrinsics.md)

docs/intrinsics/rdtscp.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ ms.assetid: f17d9a9c-88bb-44e0-b69d-d516bc1c93ee
1010

1111
**Microsoft Specific**
1212

13-
Generates the `rdtscp` instruction, writes `TSC_AUX[31:0`] to memory, and returns the 64-bit Time Stamp Counter (`TSC)` result.
13+
Generates the `rdtscp` instruction, writes `TSC_AUX[31:0]` to memory, and returns the 64-bit Time Stamp Counter (TSC) result.
1414

1515
## Syntax
1616

@@ -39,7 +39,7 @@ A 64-bit unsigned integer tick count.
3939

4040
## Remarks
4141

42-
The `__rdtscp` intrinsic generates the `rdtscp` instruction. To determine hardware support for this instruction, call the `__cpuid` intrinsic with `InfoType=0x80000001` and check bit 27 of `CPUInfo[3] (EDX)`. This bit is 1 if the instruction is supported, and 0 otherwise. If you run code that uses the intrinsic on hardware that doesn't support the `rdtscp` instruction, the results are unpredictable.
42+
The `__rdtscp` intrinsic generates the `rdtscp` instruction. To determine hardware support for this instruction, call the `__cpuid` intrinsic with `InfoType=0x80000001` and check bit 27 of `CPUInfo[3] (EDX)`. This bit is 1 if the instruction is supported, and 0 otherwise. If you run code that uses the intrinsic on hardware that doesn't support the `rdtscp` instruction, the results are unpredictable.
4343

4444
This instruction waits until all previous instructions have executed and all previous loads are globally visible. However, it isn't a serializing instruction. For more information, see the Intel and AMD manuals.
4545

0 commit comments

Comments
 (0)