Skip to content

Commit 2124981

Browse files
authored
Merge branch 'master' into mb-cmake2
2 parents e21f891 + 467fc9f commit 2124981

22 files changed

+778
-213
lines changed

docs/cpp-conformance-improvements-2017.md

Lines changed: 52 additions & 30 deletions
Large diffs are not rendered by default.

docs/cpp/TOC.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@
231231
## [Lambda Expressions in C++](lambda-expressions-in-cpp.md)
232232
### [Lambda Expression Syntax](lambda-expression-syntax.md)
233233
### [Examples of Lambda Expressions](examples-of-lambda-expressions.md)
234+
### [constexpr Lambda Expressions](lambda-expressions-constexpr.md)
234235
## [Arrays (C++)](arrays-cpp.md)
235236
### [Using Arrays (C++)](using-arrays-cpp.md)
236237
### [Initializing Arrays](initializing-arrays.md)

docs/cpp/attributes2.md

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,54 @@ ms.assetid: 748340d9-8abf-4940-b0a0-91b6156a3ff8
1010
caps.latest.revision: 11
1111
manager: "ghogen"
1212
---
13-
# C++ Standard Attributes
13+
# Attributes in C++
14+
The C++ Standard defines a set of attributes and also allows compiler vendors to define their own attributes (within a vendor-specific namespace), but compilers are required to recognize only those attributes defined in the standard.
15+
16+
In some cases, standard attributes overlap with compiler-specific declspec parameters. In Visual C++, you can use the `[[deprecated]]` attribute instead of using `declspec(deprecated)` and the attribute will be recognized by any conformant compiler. For all other declspec parameters such as dllimport and dllexport, there is as yet no attribute equivalent so you must continue to use declspec syntax. Attributes do not affect the type system, and they don’t change the meaning of a program. Compilers ignore attribute values they don't recognize.
17+
18+
**Visual Studio 2017 version 15.3 and later**(available with [/std:c++17](../build/reference/std-specify-language-standard-version.md)): In the scope of an attribute list, you can specify the namespace for all names with a single `using` introducer:
19+
20+
```cpp
21+
void g() {
22+
[[ using rpr: kernel , target(cpu,gpu)]] // equivalent to [[ rpr::kernel, rpr::target(cpu,gpu) ]]
23+
do task();
24+
}
25+
```
26+
27+
## C++ Standard Attributes
1428
In C++11, attributes provide a standardized way to annotate C++ constructs (including but not limited to classes, functions, variables, and blocks) with additional information that may or may not be vendor-specific. A compiler can use this information to generate informational messages, or to apply special logic when compiling the attributed code. The compiler ignores any attributes that it does not recognize, which means that you cannot define your own custom attributes using this syntax. Attributes are enclosed by double square brackets:
1529

1630
```
1731
[[deprecated]]
1832
void Foo(int);
1933
```
2034

21-
Attributes represent a standardized alternative to vendor-specific extensions such as #pragma directives, __declspec() (Visual C++), or \__attribute\_\_ (GNU). However, you will still need to use the vendor-specific constructs for most purposes. The standard currently specifies three attributes that a conforming compiler should recognize:
35+
Attributes represent a standardized alternative to vendor-specific extensions such as #pragma directives, __declspec() (Visual C++), or \__attribute\_\_ (GNU). However, you will still need to use the vendor-specific constructs for most purposes. The standard currently specifies the following attributes that a conforming compiler should recognize:
2236

23-
- `noreturn` -- specifies that a function never returns; in other words it always throws an exception. The compiler can adjust its compilation rules for [[noreturn]] entities.
37+
- `noreturn` Specifies that a function never returns; in other words it always throws an exception. The compiler can adjust its compilation rules for `[[noreturn]]` entities.
2438

25-
- `carries_dependency`--specifies that the function propagates data dependency ordering with respect to thread synchronization. The attribute can be applied to one or more parameters, to specify that the passed-in argument carries a dependency into the function body. The attribute can be applied to the function itself, to specify that the return value carries a dependency out of the function. The compiler can use this information to generate more efficient code.
39+
- `carries_dependency` Specifies that the function propagates data dependency ordering with respect to thread synchronization. The attribute can be applied to one or more parameters, to specify that the passed-in argument carries a dependency into the function body. The attribute can be applied to the function itself, to specify that the return value carries a dependency out of the function. The compiler can use this information to generate more efficient code.
2640

27-
- `deprecated` - **Visual Studio 2015 and later:** specifies that a function is not intended to be used, and might not exist in future versions of a library interface. The compiler can use this to generate an informational message when client code attempts to call the function. Can be applied to declaration of a class, a typedef-name, a variable, a non-static data member, a function, a namespace, an enumeration, an enumerator, or a template specialization.
41+
- `deprecated` - **Visual Studio 2015 and later:** Specifies that a function is not intended to be used, and might not exist in future versions of a library interface. The compiler can use this to generate an informational message when client code attempts to call the function. Can be applied to declaration of a class, a typedef-name, a variable, a non-static data member, a function, a namespace, an enumeration, an enumerator, or a template specialization.
42+
43+
- `[[fallthrough]]` - **Visual Studio 2017 and later:** (available with [/std:c++17](../build/reference/std-specify-language-standard-version.md)) The `[[fallthrough]]` attribute can be used in the context of [switch](switch-statement-cpp.md) statements as a hint to the compiler (or anyone reading the code) that the fallthrough behavior is intended. The Visual C++ compiler currently does not warn on fallthrough behavior, so this attribute has no effect compiler behavior.
44+
45+
- `[[nodiscard]]` **Visual Studio 2017 version 15.3 and later:** (available with [/std:c++17](../build/reference/std-specify-language-standard-version.md)) Specifies that a function's return value is not intended to be discarded. Raises warning C4834, as shown in the following example
46+
47+
```cpp
48+
[[nodiscard]]
49+
int foo(int i) { return i * i; }
50+
51+
int main()
52+
{
53+
foo(42); //warning C4834: discarding return value of function with 'nodiscard' attribute
54+
return 0;
55+
}
56+
```
2857
29-
- `fallthrough` - **Visual Studio 2017 and later:**(available with [/std:c++latest](../build/reference/std-specify-language-standard-version.md)) The `[[fallthrough]]` attribute can be used in the context of [switch](switch-statement-cpp.md) statements as a hint to the compiler (or anyone reading the code) that the fallthrough behavior is intended. The Visual C++ compiler currently does not warn on fallthrough behavior, so this attribute has no effect compiler behavior.
58+
- `[[maybe_unused]]` **Visual Studio 2017 version 15.3 and later:** (available with [/std:c++17](../build/reference/std-specify-language-standard-version.md)) Specifies that a variable, function, class, typedef, non-static data member, enum, or template specialization may intentionally not be used. The compiler does not warn when an entity marked `[[maybe_unused]]` is not used. An entity that is declared without the attribute can later be redeclared with the attribute and vice versa. An entity is considered marked after its first declaration that is marked is analyzed, and for the remainder of translation of the current translation unit.
3059
31-
**Microsoft-specific:**
60+
## Microsoft-specific attributes
3261
3362
- `gsl::suppress` -- this Microsoft-specific attribute is used for suppressing warnings from checkers that enforce [Guidelines Support Library (GSL)](https://github.com/Microsoft/GSL) rules in code. For example, consider the code snippet below
3463
@@ -55,4 +84,3 @@ void Foo(int);
5584
5685
The first two warnings fire when you compile this code with the CppCoreCheck code analysis tool installed and activated. But the third warning doesn't fire because of the attribute. You can suppress the entire bounds profile by writing [[gsl::suppress(bounds)]] without including a specific rule number. The C++ Core Guidelines are designed to help you write better and safer code. The suppress attribute makes it easy to turn off the warnings when they are not wanted.
5786
58-
The C++ standard allows compiler vendors to define their own attribute parameters (within a vendor-specific namespace), but compilers are required to recognize only those attributes defined in the standard. In Visual C++, you can use the [[deprecated]] attribute instead of using declspec (deprecated) and the attribute will be recognized by any conformant compiler. For all other declspec parameters such as dllimport and dllexport, there is as yet no standard attribute equivalent so you must continue to use declspec syntax. Attributes do not affect the type system, and they don’t change the meaning of a program. Compilers ignore attribute values they don't recognize.

docs/cpp/bool-cpp.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ translation.priority.ht:
3939
---
4040
# bool (C++)
4141
This keyword is a built-in type. A variable of this type can have values [true](../cpp/true-cpp.md) and [false](../cpp/false-cpp.md). Conditional expressions have the type `bool` and so have values of type `bool`. For example, `i!=0` now has **true** or **false** depending on the value of `i`.
42+
43+
**Visual Studio 2017 version 15.3 and later** (available with [/std:c++17](../build/reference/std-specify-language-standard-version.md)): The operand of a postfix or prefix increment or decrement operator may not be of type `bool`.
4244

4345
The values **true** and **false** have the following relationship:
4446

@@ -55,7 +57,10 @@ if (condexpr1) statement1;
5557

5658
If `condexpr1` is **true**, `statement1` is always executed; if `condexpr1` is **false**, `statement1` is never executed.
5759

58-
When a postfix or prefix `++` operator is applied to a variable of type `bool`, the variable is set to **true**. The postfix or prefix `--` operator cannot be applied to a variable of this type.
60+
When a postfix or prefix `++` operator is applied to a variable of type `bool`, the variable is set to **true**.
61+
**Visual Studio 2017 version 15.3 and later**: operator++ for bool was removed from the language and is no longer supported.
62+
63+
The postfix or prefix `--` operator cannot be applied to a variable of this type.
5964

6065
The `bool` type participates in integral promotions. An r-value of type `bool` can be converted to an r-value of type `int`, with **false** becoming zero and **true** becoming one. As a distinct type, `bool` participates in overload resolution.
6166

docs/cpp/compound-statements-blocks.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ if( Amount > 100 )
5656
Alert();
5757
}
5858
else
59+
{
5960
Balance -= Amount;
61+
}
6062
```
6163

6264
> [!NOTE]

docs/cpp/enumerations-cpp.md

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,23 +62,25 @@ enum [class|struct]
6262

6363
```
6464
// Forward declaration of enumerations (C++11):
65-
enum A : int; // non-scoped enum must have type specifiedenum class B; // scoped enum defaults to intenum class C : short;
65+
enum A : int; // non-scoped enum must have type specified
66+
enum class B; // scoped enum defaults to int but ...
67+
enum class C : short; // ... may have any integral underlying type
6668
```
6769

68-
#### Parameters
70+
## Parameters
6971
`identifier`
7072
The type name given to the enumeration.
7173

7274
`type`
7375
The underlying type of the enumerators; all enumerators have the same underlying type. May be any integral type.
7476

7577
`enum-list`
76-
Comma-separated list of the enumerators in the enumeration. Every enumerator or variable name in the scope must be unique. However, the values can be duplicated. In a unscoped enum, the scope is the surrounding scope; in a scoped enum, the scope is the `enum-list` itself.
78+
Comma-separated list of the enumerators in the enumeration. Every enumerator or variable name in the scope must be unique. However, the values can be duplicated. In a unscoped enum, the scope is the surrounding scope; in a scoped enum, the scope is the `enum-list` itself. In a scoped enum, the list may be empty which in effect defines a new integral type.
7779

7880
`class`
7981
By using this keyword in the declaration, you specify the enum is scoped, and an `identifier` must be provided. You can also use the `struct` keyword in place of `class`, as they are semantically equivalent in this context.
8082

81-
## Remarks
83+
## Enumerator scope
8284
An enumeration provides context to describe a range of values which are represented as named constants and are also called enumerators. In the original C and C++ enum types, the unqualified enumerators are visible throughout the scope in which the enum is declared. In scoped enums, the enumerator name must be qualified by the enum type name. The following example demonstrates this basic difference between the two kinds of enums:
8385

8486
```cpp
@@ -123,7 +125,7 @@ enum Suit { Diamonds = 5, Hearts, Clubs = 4, Spades };
123125

124126
Then the values of `Diamonds`, `Hearts`, `Clubs`, and `Spades` are 5, 6, 4, and 5, respectively. Notice that 5 is used more than once; this is allowed even though it may not be intended. These rules are the same for scoped enums.
125127

126-
**Casting rules**
128+
## Casting rules
127129

128130
Unscoped enum constants can be implicitly converted to `int`, but an `int` is never implicitly convertible to an enum value. The following example shows what happens if you try to assign `hand` a value that is not a `Suit`:
129131

@@ -162,7 +164,45 @@ namespace ScopedEnumConversions
162164

163165
```
164166

165-
Notice that the line `hand = account_num;` still causes the error that occurs with unscoped enums, as shown earlier. It is allowed with an explicit cast. However, with scoped enums, the attempted conversion in the next statement, `account_num = Suit::Hearts;`, is no longer allowed without an explicit cast.
167+
Notice that the line `hand = account_num;` still causes the error that occurs with unscoped enums, as shown earlier. It is allowed with an explicit cast. However, with scoped enums, the attempted conversion in the next statement, `account_num = Suit::Hearts;`, is no longer allowed without an explicit cast.
168+
169+
## Enums with no enumerators
170+
**Visual Studio 2017 version 15.3 and later** (available with [/std:c++17](../build/reference/std-specify-language-standard-version.md)): By defining an enum (regular or scoped) with an explicit underlying type and no enumerators, you can in effect introduce a new integral type that has no implicit conversion to any other type. By using this type instead of its built-in underlying type, you can eliminate the potential for subtle errors caused by inadvertent implicit conversions.
171+
172+
173+
```cpp
174+
enum class byte : unsigned char { };
175+
```
176+
177+
The new type is an exact copy of the underlying type, and therefore has the same calling convention, which means it can be used across ABIs without any performance penalty. No cast is required when variables of the type are initialized by using direct-list initialization. The following example shows how to initialize enums with no enumerators in various contexts:
178+
179+
```cpp
180+
enum class byte : unsigned char { };
181+
182+
enum class E : int { };
183+
E e1{ 0 };
184+
E e2 = E{ 0 };
185+
186+
struct X
187+
{
188+
E e{ 0 };
189+
X() : e{ 0 } { }
190+
};
191+
192+
E* p = new E{ 0 };
193+
194+
void f(E e) {};
195+
196+
int main()
197+
{
198+
f(E{ 0 });
199+
byte i{ 42 };
200+
byte j = byte{ 42 };
201+
202+
// unsigned char c = j; // C2440: 'initializing': cannot convert from 'byte' to 'unsigned char'
203+
return 0;
204+
}
205+
```
166206

167207
## See Also
168208
[C Enumeration Declarations](../c-language/c-enumeration-declarations.md)

docs/cpp/examples-of-lambda-expressions.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,15 +282,26 @@ int main()
282282

283283
### Example
284284
You can use lambda expressions in the body of a function. The lambda expression can access any function or data member that the enclosing function can access. You can explicitly or implicitly capture the `this` pointer to provide access to functions and data members of the enclosing class.
285+
**Visual Studio 2017 version 15.3 and later** (available with [/std:c++17](../build/reference/std-specify-language-standard-version.md)): Capture `this` by value (`[*this]`) when the lambda will be used in asynchronous or parallel operations where the code might execute after the original object goes out of scope.
285286

286287
You can use the `this` pointer explicitly in a function, as shown here:
287288

288289
```cpp
290+
291+
// capture "this" by reference
289292
void ApplyScale(const vector<int>& v) const
290293
{
291294
for_each(v.begin(), v.end(),
292295
[this](int n) { cout << n * _scale << endl; });
293296
}
297+
298+
// capture "this" by value (Visual Studio 2017 version 15.3 and later)
299+
void ApplyScale2(const vector<int>& v) const
300+
{
301+
for_each(v.begin(), v.end(),
302+
[*this](int n) { cout << n * _scale << endl; });
303+
}
304+
294305
```
295306
296307
You can also capture the `this` pointer implicitly:

0 commit comments

Comments
 (0)