39

When trying to print the first command line argument:

std::cout << argv[0] << std::endl; 

clang-tidy gives the warning:

warning: 'do not use pointer arithmetic' from [cppcoreguidelines-pro-bounds-pointer-arithmetic]

Is there an alternative way to use the values of argv without using pointer arithmetic? Isn't accessing a char** by any sensible method going to have to use pointer arithmetic?

I appreciate there are some specialised functions to handle command line arguments, but they seem too heavyweight for simply printing one argument.

I am writing in c++, using the clang compiler and building with cmake.

13
  • 4
    If you only need argv[0], you can use *argv. But beyond that, nope. Commented Aug 16, 2017 at 16:14
  • 1
    @spectras never an array. Function arguments cannot be arrays. Commented Aug 16, 2017 at 16:40
  • 4
    It's just implementation core guidelines ran amok. A better implementation should recognize the special case of main and stop bothering you about pointer arithmetic in this case. Commented Aug 16, 2017 at 16:54
  • 4
    @hvd Than guidelines should make an exception for main. It is a well-known interface which is not going to change, so why bother developers with this warning? Commented Aug 16, 2017 at 17:03
  • 4
    @SergeyA As I point out in my answer, it's possible to read the command-line arguments without changing the interface in a way that this guideline supports. But I do think it would be good if they at least address it. Whether that is by making an exception or by showing how to implement it without violating the guideline doesn't matter too much to me. Commented Aug 16, 2017 at 17:07

1 Answer 1

28

From clang-tidy - cppcoreguidelines-pro-bounds-pointer-arithmetic:

Pointers should only refer to single objects, and pointer arithmetic is fragile and easy to get wrong. span<T> is a bounds-checked, safe type for accessing arrays of data.

So yes:

Is there an alternative way to use the values of argv without using pointer arithmetic? Isn't accessing a char** by any sensible method going to have to use pointer arithmetic?

You're entirely correct. However, the guideline is about hiding that pointer arithmetic, letting a helper class do bounds checks before performing the arithmetic. You can construct a span<char*> from argv and argc. E.g. in C++20 you would write:

auto args = std::span(argv, size_t(argc)); 

and then use args instead of argv.

Sign up to request clarification or add additional context in comments.

13 Comments

@SergeyA That sounds like you fundamentally disagree with the guideline. Which is perfectly fair, and in that case, don't turn on that warning.
I am in agreement with the majority of them, but this particular rule I find badly thought. A branch on every access is not what I ever want in my code.
There is no bounds checking for std::span in C++20.
"constexpr reference operator[](size_type idx) const; Returns a reference to the idx-th element of the sequence. The behavior is undefined if idx is out of range"
std::span accepts size as a size_t (unsigned type), while argc is an int (signed type). Without an explicit cast, there would be a warning about implicit signed->unsigned conversion.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.