Home > OS >  Why does Clang’s -Wrange-loop-analysis warn at a for loop with a std::string_view variable? Isn’t st
Why does Clang’s -Wrange-loop-analysis warn at a for loop with a std::string_view variable? Isn’t st

Time:03-30

I have this loop:

for (const std::string_view resource : resources) { ... }

whereby resources is defined as

inline const std::string_view resources[] = { ... } 

But I get this error:

error: loop variable 'resource' of type 'const std::string_view' (aka 'const basic_string_view<char>') creates a copy from type 'const std::string_view' [-Werror,-Wrange-loop-analysis]

Why is that. I thought std::string_view was just a reference to the actual data. But here it's copied instead?

CodePudding user response:

Why is that.

You make a copy because the loop variable is not a reference (and has the same type as the element).

I thought std::string_view was just a reference to the actual data.

That's what it is conceptually. More specifically, it is a class that contains a pointer to the data, and the size (or alternatively, pointer to the end; it doesn't matter). You make a copy of this conceptual "reference" i.e. that class instance.


Note that -Wrange-loop-analysis is not enabled by default nor by -Wall nor by -Wextra (at least in Clang 9). Such "warnings" often don't necessarily imply that there is anything wrong with the program. They may be either informative hints, or they may have high rate of false positives.

Clang no longer produces the warning for the given example since version 10. This is what the release notes say:

-Wrange-loop-analysis got several improvements. ... It no longer warns when an object of a small, trivially copyable type is copied.

So, my suggested solution is to upgrade your compiler and/or don't explicitly enable -Wrange-loop-analysis.

CodePudding user response:

string_view is a wrapper for a pointer to a string and its size. When you do:

for (const std::string_view resource : resources)

You are copying those variables, so you get a warning. The string is not being copied, but there is some non-zero amount of data being copied.

If you used a refererence like:

for (const std::string_view& resource : resources)

Then even the pointer and size members will no longer be copied.

CodePudding user response:

I just read that the ctor is the copy constructor. That explains it.

  1. Copy constructor. Constructs a view of the same content as other. After construction, data() is equal to other.data(), and size() is equal to other.size().
  • Related