<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/119067>119067</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [FR] Clang-Tidy QuickFix for `argv` in `main` and General Hints for `cppcoreguidelines-pro-bounds-pointer-arithmetic`
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang-tidy
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          FalcoGer
      </td>
    </tr>
</table>

<pre>
    ## The problem

The rule `cppcoreguidelines-pro-bounds-pointer-arithmetic` triggers when indexing `argv` in the `main` function, as it considers this to be unsafe pointer arithmetic. However, in this case, `argv` is a special array with a predictable size (`argc`) that could benefit from a specialized fix to make it's access safe.

## The Solution

Since `std::span` is a safer way to handle array bounds and provides better index checking, it can be used as a more robust alternative to raw pointer arithmetic. Additionally it provides iterators, which can be used in all standard library functions that accept them. We can not use `std::array` here because the number of program arguments is not known at compile time.

Alternatively, a `std::vector<std::string_view>` could be used. Benefits would be the use of `std::string_view`, which is more flexible and type safe, and generally a lot easier to work with than raw c-strings. The downside is the dynamic memory allocation for the vector, rather than the minimal size overhead of the `std::span`.

In cases where a predictable function signature is not standardized like in `main` (ie. we don't know which parameter, if any (global, `#define`, weird parameter names and/or positions, etc), denotes the size), a helpful hint could be given instead, like "Wrap array into std::span and replace indexing with std::span::at()", or "Replace raw-array parameter with std::span for dynamically sized arrays, or std::array for statically sized arrays" or something of the sort.

## Example

For main(int, char**) specifically, I propose that this, or a similar, quickfix be provided:

```cpp
int main(int argc, char** argv)
{
  const auto PROG_NAME = argv[0];
//                       ^~~~
// Do not use pointer arithmetic (clang-tidy cppcoreguidelines-pro-bounds-pointer-arithmetic)
}
```

In this specific case, it should propose a quickfix, or at least a helpful hint, and replace the access with an `std::span<char*>`

```cpp
// inserted headers
#include <cstddef>   // for std::size_t
#include <span>      // for std::span

int main(int argc, char** argv)
{
  // inserted
  const std::span<char*> ARGS(argv, static_cast<std::size_t>(argc));
  // quickfix replaces all instances of argv[i] with ARGS.at(i)
  const auto PROG_NAME = ARGS.at(0);
}
```

or

```cpp
// inserted headers
#include <cstddef> // for std::size_t
#include <string_view> // for std::string_view
#include <vector>      // for std::vector

int main(int argc, char** argv)
{
  // inserted
  const std::vector<const std::string_view> ARGS(argv, static_cast<std::size_t>(argc));
  // replace all instances of argv[i] with ARGS.at(i)
  const auto PROG_NAME = ARGS.at(0);
}
```

## Example 2
```cpp
void foo(int[] arr, const SomeObj& obj)
//       ^~~~~
//       Hint: replace int[] type with `std::span<int>` or `std::array<int, N>` here.
{
    arr[obj.getArrIdx()] = 42; // array bounds can not be determined for an automated fix
// ^~~~~~~~~~~~~~~~~~~~
//  Warning: cppcoreguidelines-pro-bounds-pointer-arithmetic
//  consider replacing type of arr with std::array for a statically sized array, or std::span for a dynamically sized array
//  Related: Hint: replace arr type here.
}
```

## Alternatives
Exclude argv indexing from `cppcoreguidelines-pro-bounds-pointer-arithmetic`, perhaps with an option in `cppcoreguidelines-pro-bounds-pointer-arithmetic`, and create a new rule for the specific case of indexing `argv`, to keep the rules simple and separate concerns.
Specific rule settings could then be given, for example to handle some of the considerations noted below (use `at()` or `[]`; should type be `const char*` or `char*`; etc).

### Notes

- If `std::arguments` proposal [P3474](https://wg21.link/p3474) gets accepted, this needs to be revisited once implemented, as that would become the new, best way to address program arguments (`std::arguments.at(1).string()`). In that case this should probably be made into a new rule and excluded from `cppcoreguidelines-pro-bounds-pointer-arithmetic`.
- Consideration should be given if the inserted `ARGS` span should have the type `const std::span<const char*>` instead, or only if `argv` is already `const` in the `main` signature.
- `std::span::at()` will throw, consideration should be given if indexing should be done with `operator[]` instead.
- Considerations could be given if you want to possibly create an `const std::vector<const std::string_view>` instead, though this has a tiny allocation and runtime overhead associated.

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEWEtz2zgS_jX0pcsqibRk6-CD_MrksJnZZKpyTDXJlogYBLgAKFlzyG_f6gYfeiW1yc7WulxlCwK6G19__QJ6rzaG6D6ZPyTzpytsQ2Xd_Qvqwr4jd5Xbcn-fpFmSZvBnRdA4m2uqk-kqma54wbWaIFlMi6YprKNNq0rSypC_bpy9zm1rSn_dWGUCuWt0KlQ1BVUkiykEpzYbch52FRlQpqQ3ZTYsDN1myzuUgVCJ-BqV4ZV1a4qgrEnSR0APKkBhjVcliwmV8hAs5ASt8bgm6PTCqHcCv9kdbcmxABGvPBToiT8favaA4BsqFGpA53APOxUqQGgclaoImGsCr_4iSNK7eJAvlaRLCBWyWa0uISdDaxVg7Ww9ClR_UQlr9cbG1vhKoEKS3nrAoiDvgU2fRIQPkP9kdSs3ly8-KVMIMD6USbZKspVv0IyW45oc7HDPKio0pabuFtEjgKZkX25VSR5yCoySeACKiopXZTYCUIACjQDqqWTAEWrrCJzNWx8AdSBnMKgtsSKHu4uQr8pSsemo9Z5lDopVIIfBOs_KdpUqqiN9ygBqDT6gKdGVoFXu0O0HEvgINcPWBGZKPYHPJCKMDSzjCCEBgCGqyBHkVCDvYIKZts7JgV2zaRuHNaDbtDWZ4BlPFvZq7M6AOLZulCYIqu69tBph0Hth5pHeLRXBuiR7HH0VnDKbL1tFuyR7ZpN6usjFJ_AQeeNh16-zmWyuXR97_UASs6-HUfnoqLWmN8VUZYeHfUNCDbHRlLAhQ068gqBtAEKvyLErd9a9RsaHCo14triOyvxE-FjanQQeq2Ljyr3BWhVQU23dnh1nC2Qvwdo62dHhkD6Cw1CxHhbN39TKqBp1jCe7JVcRlnzVLvpPSd7h_t5I6EoCcXQSmz1JgBMchtZR78qeTxKGWnH8mcMck6R3iiaw4zuaJL2Nzu-AbdBhTaFLIGtAs-cDG21z1F0SSdKspLUy1LuElCvHk2CwJgnBJH2xDhrrJTwkCigUSbrk_0oyNlAEl4HplhEq0s261VApM-YZ2KitZFEfCEveKDdL0vSzw6YLfmWChSMwhQaOGo0FjSlYHH8MeoygwMmO7UhZg3Us_2N32uHuOqoZb3ouSNjQcUWY58UNctB3Qo8jVk74gOHigVQO2JpCxZZ3nPHWheMU-vyGdaMprjHq4u30TpnAWosKXZKu5HcZ8_Q66uNv33NeaKxkCwxSNDpTEbyqlUahw79aVbxyXs-pz3FykWjHYhp_i6ZJpiv23WgCSPk4sgOkFKVLPnr7kExXIKUuALbBwh8ff3_35cPqH8-QZE9x6_xhmsyfkuxBLv2SpC9w-SeZP3_79m3c9WSHdHmevZnchUazuQ6q3MPPlvnO_qdDAIbgleLbYz1UYRXAV8LqHnQckO1RD6AJGYujYOjTWs9nZkJXU2PxNufJJHvsIZdEfNFXHU7KeHKBSuDsRM5HcilT6LYkYEk-lCWtk-yZUY6H1od8Zup-CWfnoiHPnXcuneMNYtmv0ObE_AMqfR8KWH189ylJ76K0xy7-vhTow1EhixfKnuPWmLqWkYOD4iEsOr94qeqcqdDwJ7vuCayS-VN0FaufSLpR8TI_YP-4dzoov0g56_4u9_6Mc49q_eWTB1tOj_fNww_Y0W35X_JjaGFOeXN8ub-RNH0M_5-oclw1ID1nzdaqEtbWdjVExieuSgK36P9ka_o9_5qkC7D8Z3mamGMi_na6_BvLy1YHZbkXLw2cXPpCHpNT0kxyXT7re-OG9BE-dLu4Z5oc0ADE-vmDzb9ONhRWzr0v37p6P38S-G7SJHvoPXQ0T_Q9d05QcuWvleEZh3O1EUfUGOLQM962u_7JzwEan9EZnkSy1U_XnVFIPx92cHKTIDAKlU47lLHhwO-0HKctytDT4Pe6mgNbPpJmGPhCp05mW8Su0S3fp-XBwMFp6vktpgsOjbGJk5nzlyZzvmNDrsJmLJy2kWY6dsq_JpJLc-EIA1d0Q7v4dtBPB0d9AHvnwoMASwkWXokaOcMCPHdgTTfheOLeMxB7vSBnPCP5qZcs-jyFwFNM1zmHiszQPrN8toe6sB-HZ-4w--ayZxTGGZS7dO7Atd1xs9RNnUOrPMRjjGH-J3voOxzxeB4fUCRn9Il6ODUu8LE4HRx1tsyHDzwoxMVreL8-if5ukmWZsaNCDcn84Y_s5vaGLUrvqhAaz9uFp7tNOptoZV6T9KWRTekSNhR8N2mTjBfSvBmisn9zcbRVXjEWjD2IU1hx3I7dsN4PtAUDKrM37fj7nHzoHyywLB03befDeHxrOb9bzOkzxiaWpAF8XgLpNXl2R2nhuescOswcc71n-2ssKU5IB-xkUlEMr_K_iKiJeObxkDi9CePoFtk1tCHJYir1dDEFSTLd_gq3ETjhzkCcs1buiE4x4x8Mh9aBNXrPSk9evbQjLPeD4MvPcMNMHS92Xo2OpsXFFHZKawiVs7u-Pv4QiCH2x-9Ka8baZ5v4cDTEVH-3C0D7sxl5DXvbwg5NYLY11nvFHOhzk7mA6n_WAJ2AHCrbbqpIuEoez4IyR08jMq20Jqj64N0DvbeF4kLBt7kq77NymS3xiu5nt1k2X9xmi-yqui8WeYaz9O6mXE5xjcUiu5vNs-X8ZjFdznBaXqn7dJrezNLp7WyaLtNsktI6T4s5zW4Jl7Pb2-RmSjUqPdF6W0-s21wp71u6n82W08XtlcactJeX4TQdZ0Ae_udPV-6eT13n7cYnN1OtfPCjnKCCljfll4_cOzzK4T95gPwnDwMv6k3y7PFT7wG_GJd38XFKKqXvt_986F21Tt8fJ7iNClWbTwpbJ-kL29z9YVlfqQhJ-iJA-CR96bDY3qf_DgAA____14VS">