Skip to content

Repo sync for protected CLA branch #2586

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Nov 9, 2020
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 58 additions & 19 deletions docs/c-language/type-qualifiers.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
---
title: "Type Qualifiers"
ms.date: "11/04/2016"
description: "Describes type qualifiers for the C language used in the Microsoft Visual C compiler"
ms.date: "11/6/2020"
helpviewer_keywords: ["volatile keyword [C], type qualifier", "type qualifiers", "volatile keyword [C]", "qualifiers for types", "const keyword [C]", "memory, access using volatile", "volatile keyword [C], type specifier"]
ms.assetid: bb4c6744-1dd7-40a8-b4eb-f5585be30908
---
# Type Qualifiers

Type qualifiers give one of two properties to an identifier. The **`const`** type qualifier declares an object to be nonmodifiable. The **`volatile`** type qualifier declares an item whose value can legitimately be changed by something beyond the control of the program in which it appears, such as a concurrently executing thread.

The two type qualifiers, **`const`** and **`volatile`**, can appear only once in a declaration. Type qualifiers can appear with any type specifier; however, they cannot appear after the first comma in a multiple item declaration. For example, the following declarations are legal:
The type qualifiers, **`const`**, **`restrict`**, and **`volatile`**, can appear only once in a declaration. Type qualifiers can appear with any type specifier; however, they can't appear after the first comma in a multiple item declaration. For example, the following declarations are legal:

```
```c
typedef volatile int VI;
const int ci;
```

These declarations are not legal:
These declarations aren't legal:

```
```c
typedef int *i, volatile *vi;
float f, const cf;
```
Expand All @@ -26,31 +27,69 @@ Type qualifiers are relevant only when accessing identifiers as l-values in expr

## Syntax

*type-qualifier*:
**constvolatile**
*`type-qualifier`*:\
 **`const`**\
 **`restrict`**\
 **`volatile`**

## `const` and `volatile`

The following are legal **`const`** and **`volatile`** declarations:

```
int const *p_ci; /* Pointer to constant int */
int const (*p_ci); /* Pointer to constant int */
int *const cp_i; /* Constant pointer to int */
int (*const cp_i); /* Constant pointer to int */
int volatile vint; /* Volatile integer */
```c
int const *p_ci; // Pointer to constant int
int const (*p_ci); // Pointer to constant int
int *const cp_i; // Constant pointer to int
int (*const cp_i); // Constant pointer to int
int volatile vint; // Volatile integer
```

If the specification of an array type includes type qualifiers, the element is qualified, not the array type. If the specification of the function type includes qualifiers, the behavior is undefined. Neither **`volatile`** nor **`const`** affects the range of values or arithmetic properties of the object.

This list describes how to use **`const`** and **`volatile`**.
If the specification of an array type includes type qualifiers, the element is qualified, not the array type. If the specification of the function type includes qualifiers, the behavior is undefined. **`volatile`** and **`const`** don't affect the range of values or arithmetic properties of the object.

- The **`const`** keyword can be used to modify any fundamental or aggregate type, or a pointer to an object of any type, or a **`typedef`**. If an item is declared with only the **`const`** type qualifier, its type is taken to be **const int**. A **`const`** variable can be initialized or can be placed in a read-only region of storage. The **`const`** keyword is useful for declaring pointers to **`const`** since this requires the function not to change the pointer in any way.

- The compiler assumes that, at any point in the program, a **`volatile`** variable can be accessed by an unknown process that uses or modifies its value. Therefore, regardless of the optimizations specified on the command line, the code for each assignment to or reference of a **`volatile`** variable must be generated even if it appears to have no effect.
- The compiler assumes that, at any point in the program, a **`volatile`** variable can be accessed by an unknown process that uses or modifies its value. Regardless of the optimizations specified on the command line, the code for each assignment to or reference of a **`volatile`** variable must be generated even if it appears to have no effect.

If **`volatile`** is used alone, **`int`** is assumed. The **`volatile`** type specifier can be used to provide reliable access to special memory locations. Use **`volatile`** with data objects that may be accessed or altered by signal handlers, by concurrently executing programs, or by special hardware such as memory-mapped I/O control registers. You can declare a variable as **`volatile`** for its lifetime, or you can cast a single reference to be **`volatile`**.

- An item can be both **`const`** and **`volatile`**, in which case the item couldn't be legitimately modified by its own program, but could be modified by some asynchronous process.

## `restrict`

If **`volatile`** is used alone, **`int`** is assumed. The **`volatile`** type specifier can be used to provide reliable access to special memory locations. Use **`volatile`** with data objects that may be accessed or altered by signal handlers, by concurrently executing programs, or by special hardware such as memory-mapped I/O control registers. You can declare a variable as **`volatile`** for its lifetime, or you can cast a single reference to be **`volatile`**.
The **`restrict`** type qualifier, introduced in C99, can be applied to pointer declarations. It qualifies the pointer, not what it points at.

- An item can be both **`const`** and **`volatile`**, in which case the item could not be legitimately modified by its own program, but could be modified by some asynchronous process.
**`restrict`** is an optimization hint to the compiler that no other pointer in the current scope refers to the same memory location. That is, only the pointer or a value derived from it (such as pointer + 1) is used to access the object during the lifetime of the pointer. This helps the compiler produce more optimized code. C++ has an equivalent mechanism, [`__restrict`](../cpp/extension-restrict.md)

Keep in mind that **`restrict`** is a contract between you and the compiler. If you do alias a pointer marked with **`restrict`**, the result is undefined.

Here's an example that uses **`restrict`**:

```c
void test(int* restrict first, int* restrict second, int* val)
{
*first += *val;
*second += *val;
}

int main()
{
int i = 1, j = 2, k = 3;
test(&i, &j, &k);

return 0;
}

// Marking union members restrict tells the compiler that
// only z.x or z.y will be accessed in any scope, which allows
// the compiler to optimize access to the members.
union z
{
int* restrict x;
double* restrict y;
};
```

## See also

[`/std` (Specify Language Standard Version)](../build/reference/std-specify-language-standard-version.md)\
[Declarations and Types](../c-language/declarations-and-types.md)
9 changes: 5 additions & 4 deletions docs/cpp/arrays-cpp.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
title: "Arrays (C++)"
ms.date: 08/03/2020
description: "Learn how to declare and use the native array type in the standard C++ programming language."
ms.date: 11/08/2020
helpviewer_keywords: ["declaring arrays [C++], about declaring arrays", "multidimensional arrays [C++]", "arrays [C++]"]
ms.assetid: 3f5986aa-485c-4ba4-9502-67e2ef924238
---
Expand Down Expand Up @@ -127,7 +128,7 @@ When an array is passed to a function, it's passed as a pointer to the first ele
The following example shows a function that accepts an array and a length. The pointer points to the original array, not a copy. Because the parameter isn't **`const`**, the function can modify the array elements.

```cpp
void process(double p*, const size_t len)
void process(double *p, const size_t len)
{
std::cout << "process:\n";
for (size_t i = 0; i < len; ++i)
Expand All @@ -137,10 +138,10 @@ void process(double p*, const size_t len)
}
```

Declare the array as const to make it read-only within the function block:
Declare and define the array parameter `p` as **`const`** to make it read-only within the function block:

```cpp
void process(const double p*, const size_t len);
void process(const double *p, const size_t len);
```

The same function can also be declared in these ways, with no change in behavior. The array is still passed as a pointer to the first element:
Expand Down
22 changes: 11 additions & 11 deletions docs/cpp/extension-restrict.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
---
title: "__restrict"
ms.date: "10/10/2018"
title: "`__restrict`"
description: "Describes the Microsoft Visual C++ `__restrict` keyword."
ms.date: "11/6/2020"
f1_keywords: ["__restrict_cpp", "__restrict", "_restrict"]
helpviewer_keywords: ["__restrict keyword [C++]"]
ms.assetid: 2d151b4d-f930-49df-bd16-d8757ec7fa83
---
# __restrict
# `__restrict`

Like the **__declspec ( [restrict](../cpp/restrict.md) )** modifier, the **`__restrict`** keyword indicates that a symbol is not aliased in the current scope. The **`__restrict`** keyword differs from the `__declspec ( restrict )` modifier in the following ways:
Like the **`__declspec` ( [`restrict`](../cpp/restrict.md) )** modifier, the **`__restrict`** keyword (two leading underscores '_') indicates that a symbol isn't aliased in the current scope. The **`__restrict`** keyword differs from the `__declspec (restrict)` modifier in the following ways:

- The **`__restrict`** keyword is valid only on variables, and `__declspec ( restrict )` is only valid on function declarations and definitions.
- The **`__restrict`** keyword is valid only on variables, and `__declspec (restrict)` is only valid on function declarations and definitions.

- **`__restrict`** is similar to **`restrict`** from the C99 spec, but **`__restrict`** can be used in C++ or C programs.
- **`__restrict`** is similar to [`restrict`](../c-language/type-qualifiers.md#restrict) for C starting in C99, but **`__restrict`** can be used in both C++ and C programs.

- When **`__restrict`** is used, the compiler will not propagate the no-alias property of a variable. That is, if you assign a **`__restrict`** variable to a non-**`__restrict`** variable, the compiler will still allow the non-__restrict variable to be aliased. This is different from the behavior of the **`restrict`** keyword from the C99 specification.
- When **`__restrict`** is used, the compiler won't propagate the no-alias property of a variable. That is, if you assign a **`__restrict`** variable to a non-**`__restrict`** variable, the compiler will still allow the non-__restrict variable to be aliased. This is different from the behavior of the C99 C language **`restrict`** keyword.

Generally, if you affect the behavior of an entire function, it is better to use `__declspec ( restrict )` than the keyword.
Generally, if you want to affect the behavior of an entire function, use **`__declspec (restrict)`** instead of the keyword.

For compatibility with previous versions, **_restrict** is a synonym for **`__restrict`** unless compiler option [/Za \(Disable language extensions)](../build/reference/za-ze-disable-language-extensions.md) is specified.
For compatibility with previous versions, **`_restrict`** is a synonym for **`__restrict`** unless compiler option [`/Za` \(Disable language extensions)](../build/reference/za-ze-disable-language-extensions.md) is specified.

In Visual Studio 2015 and later, **`__restrict`** can be used on C++ references.

> [!NOTE]
> When used on a variable that also has the [volatile](../cpp/volatile-cpp.md) keyword, **`volatile`** will take precedence.
> When used on a variable that also has the [`volatile`](../cpp/volatile-cpp.md) keyword, **`volatile`** will take precedence.

## Example

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ return _hr; \
The string literal should be what you would otherwise put following a *`#pragma`* statement. For example:

```c
#pragma message("--the #pragma way")
#pragma message("the #pragma way")
_Pragma ("message( \"the _Pragma way\")")
```

Expand Down
40 changes: 20 additions & 20 deletions docs/standard-library/ios-typedefs.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
---
title: "&lt;ios&gt; typedefs"
ms.date: "11/04/2016"
title: "`<ios>` typedefs"
description: "Describes the C++ standard template library (STL) `<ios>` typedefs that support the `ios` class from the old `iostream` library."
ms.date: "11/06/2020"
f1_keywords: ["iosfwd/std::ios", "iosfwd/std::streamoff", "iosfwd/std::streampos", "iosfwd/std::streamsize", "iosfwd/std::wios", "iosfwd/std::wstreampos"]
ms.assetid: 0b962632-3439-44de-bf26-20c67a7f0ff3
---
# &lt;ios&gt; typedefs
# `<ios>` typedefs

## <a name="ios"></a> ios
## `ios`

Supports the ios class from the old iostream library.
Supports the `ios` class from the old `iostream` library.

```cpp
typedef basic_ios<char, char_traits<char>> ios;
```

### Remarks

The type is a synonym for class template [basic_ios](../standard-library/basic-ios-class.md), specialized for elements of type **`char`** with default character traits.
The type is a synonym for class template [`basic_ios`](../standard-library/basic-ios-class.md), specialized for elements of type **`char`** with default character traits.

## <a name="streamoff"></a> streamoff
## `streamoff`

Supports internal operations.

Expand All @@ -32,9 +32,9 @@ Supports internal operations.

### Remarks

The type is a signed integer that describes an object that can store a byte offset involved in various stream positioning operations. Its representation has at least 32 value bits. It is not necessarily large enough to represent an arbitrary byte position within a stream. The value `streamoff(-1)` generally indicates an erroneous offset.
The type is a signed integer. It describes an object that can store a byte offset in stream positioning operations. Its representation has at least 32 value bits. It isn't necessarily large enough to represent an arbitrary byte position within a stream. The value `streamoff(-1)` generally indicates an erroneous offset.

## <a name="streampos"></a> streampos
## `streampos`

Holds the current position of the buffer pointer or file pointer.

Expand All @@ -44,7 +44,7 @@ typedef fpos<mbstate_t> streampos;

### Remarks

The type is a synonym for [fpos](../standard-library/fpos-class.md)< `mbstate_t`>.
The type is a synonym for [`fpos`](../standard-library/fpos-class.md)< `mbstate_t`>.

### Example

Expand All @@ -61,15 +61,15 @@ int main( )
ofstream x( "iostream.txt" );
x << "testing";
streampos y = x.tellp( );
cout << y << endl;
cout << streamoff(y) << '\n';
}
```

```Output
7
```

## <a name="streamsize"></a> streamsize
## `streamsize`

Denotes the size of the stream.

Expand All @@ -83,11 +83,11 @@ Denotes the size of the stream.

### Remarks

The type is a signed integer that describes an object that can store a count of the number of elements involved in various stream operations. Its representation has at least 16 bits. It is not necessarily large enough to represent an arbitrary byte position within a stream.
The type is a signed integer that describes an object that can store a count of the number of elements involved in various stream operations. Its representation has at least 16 bits. It isn't necessarily large enough to represent an arbitrary byte position within a stream.

### Example

After compiling and running the following program, look at the file test.txt to see the effect of setting `streamsize`.
After compiling and running the following program, look at the file `test.txt` to see the effect of setting `streamsize`.

```cpp
// ios_streamsize.cpp
Expand All @@ -105,19 +105,19 @@ int main( )
}
```

## <a name="wios"></a> wios
## `wios`

Supports the wios class from the old iostream library.
Supports the `wios` class from the old `iostream` library.

```cpp
typedef basic_ios<wchar_t, char_traits<wchar_t>> wios;
```

### Remarks

The type is a synonym for class template [basic_ios](../standard-library/basic-ios-class.md), specialized for elements of type **`wchar_t`** with default character traits.
The type is a synonym for class template [`basic_ios`](../standard-library/basic-ios-class.md), specialized for elements of type **`wchar_t`** with default character traits.

## <a name="wstreampos"></a> wstreampos
## `wstreampos`

Holds the current position of the buffer pointer or file pointer.

Expand All @@ -127,7 +127,7 @@ typedef fpos<mbstate_t> wstreampos;

### Remarks

The type is a synonym for [fpos](../standard-library/fpos-class.md)< `mbstate_t`>.
The type is a synonym for [`fpos`](../standard-library/fpos-class.md)< `mbstate_t`>.

### Example

Expand Down