You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/c-runtime-library/reference/vsnprintf-vsnprintf-vsnprintf-l-vsnwprintf-vsnwprintf-l.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -125,7 +125,7 @@ See [Behavior summary](#behavior-summary) for details.
125
125
126
126
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`*).
127
127
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.
129
129
130
130
> [!IMPORTANT]
131
131
> 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).
Copy file name to clipboardExpand all lines: docs/cpp/inline-functions-cpp.md
+69-37Lines changed: 69 additions & 37 deletions
Original file line number
Diff line number
Diff line change
@@ -20,35 +20,38 @@ A function defined in the body of a class declaration is implicitly an inline fu
20
20
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.
@@ -152,13 +155,15 @@ A `Point` class can be defined as follows:
152
155
153
156
```cpp
154
157
// when_to_use_inline_functions.cpp
158
+
// compile with: /c
155
159
classPoint
156
160
{
157
161
public:
158
-
// Define "accessor" functions as
159
-
// reference types.
162
+
// Define "accessor" functions
163
+
// as reference types.
160
164
unsigned& x();
161
165
unsigned& y();
166
+
162
167
private:
163
168
unsigned _x;
164
169
unsigned _y;
@@ -168,13 +173,11 @@ inline unsigned& Point::x()
168
173
{
169
174
return _x;
170
175
}
176
+
171
177
inlineunsigned& Point::y()
172
178
{
173
179
return _y;
174
180
}
175
-
int main()
176
-
{
177
-
}
178
181
```
179
182
180
183
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
193
196
```cpp
194
197
#include<iostream>
195
198
196
-
#definemult(a, b) a * b
199
+
#definemult1(a, b) a * b
200
+
#define mult2(a, b) (a) * (b)
201
+
#define mult3(a, b) ((a) * (b))
197
202
198
203
inlineintmultiply(int a, int b)
199
204
{
@@ -202,40 +207,67 @@ inline int multiply(int a, int b)
std::cout << mult(2, 2.2) << std::endl>>; // no warning
215
+
std::cout << mult3(2, 2.2) << std::endl; // no warning
209
216
std::cout << multiply(2, 2.2); // Warning C4244 'argument': conversion from 'double' to 'int', possible loss of data
210
217
}
211
218
```
212
219
213
220
```Output
214
-
35
215
-
100
221
+
33
222
+
72
223
+
2
224
+
2
216
225
4.4
217
226
4
218
227
```
219
228
220
229
Here are some of the differences between the macro and the inline function:
221
230
222
231
- 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))`.
224
233
- 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.
225
234
- 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:
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.
When performance optimization is needed, consider using:
66
65
67
-
- The [`array`](../standard-library/array-class-stl.md) type when embedding is important, for example, as a class member.
68
-
69
66
- Unordered associative containers such as [`unordered_map`](../standard-library/unordered-map-class.md). These have lower per-element overhead and constant-time lookup, but they can be harder to use correctly and efficiently.
70
-
71
67
- Sorted `vector`. For more information, see [Algorithms](../standard-library/algorithms.md).
72
68
73
69
Don't use C-style arrays. For older APIs that need direct access to the data, use accessor methods such as `f(vec.data(), vec.size());` instead. For more information about containers, see [C++ Standard Library Containers](../standard-library/stl-containers.md).
@@ -79,11 +75,8 @@ Before you assume that you need to write a custom algorithm for your program, fi
79
75
Here are some important examples:
80
76
81
77
-`for_each`, the default traversal algorithm (along with range-based `for` loops).
82
-
83
78
-`transform`, for not-in-place modification of container elements
84
-
85
79
-`find_if`, the default search algorithm.
86
-
87
80
-`sort`, `lower_bound`, and the other default sorting and searching algorithms.
88
81
89
82
To write a comparator, use strict **`<`** and use *named lambdas* when you can.
description: "Learn more about: Compiler Error C2385"
3
3
title: "Compiler Error C2385"
4
-
ms.date: "11/04/2016"
4
+
ms.date: "1/19/2024"
5
5
f1_keywords: ["C2385"]
6
6
helpviewer_keywords: ["C2385"]
7
-
ms.assetid: 6d3dd1f2-e56d-49d7-865c-6a9acdb17417
8
7
---
9
8
# Compiler Error C2385
10
9
11
-
ambiguous access of 'member'
10
+
> ambiguous access of 'member'
12
11
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:
14
13
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.
18
18
19
19
## Example
20
20
21
-
The following sample generates C2385.
21
+
The following sample generates C2385:
22
22
23
23
```cpp
24
24
// C2385.cpp
25
-
// C2385 expected
26
-
#include<stdio.h>
27
-
28
25
structA
29
26
{
30
-
void x(int i)
31
-
{
32
-
printf_s("\nIn A::x");
33
-
}
27
+
void func1(int i) {}
28
+
void func2() {}
34
29
};
35
30
36
31
structB
37
32
{
38
-
void x(char c)
39
-
{
40
-
printf_s("\nIn B::x");
41
-
}
33
+
void func1(char c) {}
34
+
void func2() {}
42
35
};
43
36
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
+
structC : 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
+
};
53
44
54
45
intmain()
55
46
{
56
-
C aC;
57
-
aC.x(100);
58
-
aC.x('c');
59
-
}
47
+
C c;
60
48
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
+
}
66
58
```
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:
Copy file name to clipboardExpand all lines: docs/error-messages/compiler-warnings/c4834.md
+2-2Lines changed: 2 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,7 @@
1
1
---
2
2
description: "Learn about the cause and fixes for Compiler warning (level 1) C4834."
3
3
title: "Compiler warning (Level 1) C4834"
4
-
ms.date: 07/26/2021
4
+
ms.date: 01/18/2024
5
5
f1_keywords: ["C4834"]
6
6
helpviewer_keywords: ["C4834"]
7
7
---
@@ -11,7 +11,7 @@ helpviewer_keywords: ["C4834"]
11
11
12
12
## Remarks
13
13
14
-
Starting in the C++17 Standard, the `[[nodiscard]]` attribute specifies that a function's return value isn't intended to be discarded. If a caller discards the return value, the compiler generates warning C4834.
14
+
Starting in the C++17 Standard, the `[[nodiscard]]` attribute specifies that a function's return value isn't intended to be discarded. If a caller discards the return value, the compiler generates warning C4834. Although this attribute was introduced in C++17, the compiler respects this attribute and generates warnings related to it when using `/std:c++14` and later.
15
15
16
16
To resolve this warning, consider why your code doesn't use the return value. Your use of the function may not match its intent. You can circumvent the warning by assigning the value to **`std::ignore`** or by casting it to **`void`** if discarding the value is intentional.
17
17
Assignment to **`std::ignore`** is preferred over casting to **`void`** in C++11 and higher, as it makes your intent clearer and will not trigger [Warning C26457](../../code-quality/c26457.md) if enabled in your code analysis settings.
0 commit comments