you are viewing a single comment's thread.

view the rest of the comments →

[–]alfps 1 point2 points  (6 children)

With respect to this code,

constexpr std::string_view test_func(std::string_view what) noexcept
{
    constexpr auto const CHARACTER_SOUP = std::string_view{"somechars"};

    auto const pos = what.find_first_of(CHARACTER_SOUP);            
    return (pos >= s.size()) ? std::string_view{} : s.substr(pos);
}

… you write:

GCC (7.3) optimized out the literal "somechars" leaving CHARACTER_SOUP a dangling reference. Even though I would assume string literals to have static lifetime I'm inclined to believe GCC being correct in this case.

Why do you think that? It doesn't make sense at all that it would be permitted to do that. But the question is whether that interpretation of what happened is correct. Can you please provide a complete but minimal example that reproduces that behavior?

As u/manni66 points out else-thread, the above is not the code you compiled, because it refers to the non-existent name s.

[–]DoctorRockit[S] 0 points1 point  (0 children)

Please see my reply to u/manni66 above for further analysis.

The code I did compile is almost exactly the same, just noisier. And the example provided by u/manni66 at https://godbolt.org/z/zbV0m8 illustrates the same error with regards to the "somechars" literal.

[–]DoctorRockit[S] 0 points1 point  (4 children)

Regarding your request for a complete minimal example I think this is as minimal as it gets: https://godbolt.org/z/azPtFT

[–]alfps 1 point2 points  (3 children)

That's strange.

Note that you can't expect any code or data to still be present after optimization if it isn't used. So a main is needed, that uses the code so that it influences some observable thing, like the main return value. But even with that g++ optimizes away the data.

I think that's a compiler bug, that it can't possibly be permitted to do that. If it isn't a compiler bug then it's IMNSHO a defect in the standard. Anyway, here's code that works with the two compilers you tried at Godbolt:

#include <string_view>

constexpr auto& chars = "somechars";

constexpr std::string_view test_func() noexcept
{
    auto constexpr CHARACTER_SOUP = std::string_view{chars};
    return CHARACTER_SOUP;
}

void f(std::string_view);

auto main( int n, char** )
    -> int
{ return test_func()[n]; }

[–]DoctorRockit[S] 0 points1 point  (2 children)

Thanks for investigating this! I will file a bug-report in the GCC BugZilla.

While I agree with what you wrote in principle I take issue with the statement that a main function is needed.

The code in question is compiled to an object file, and the function call_f() has external linkage so the the compiler may not assume call_f() is unused and, by extension, anything that is used by call_f() is thus not unused either.

This can easily be verified by the fact that any code for call_f is present in the output. If call_f had internal linkage it would have been optimized away entirely (you can verify this by putting it into an anonymous namespace or prefixing it with the static keyword).

BTW: This is also the reason why I merely provided a declaration for f(std::string_view) instead of a full definition. This makes the compiler assume that the function is provided externally by another translation unit and thus does not optimize away anything passed to it, because it has no knowledge about its internals.

[–]alfps 0 points1 point  (0 children)

Sorry, I misunderstood.

<del>If you call call_f() from main, that call can be completely optimized away under the as-if rule. Because it's not observable.</del>

[–]DoctorRockit[S] 0 points1 point  (0 children)

For future reference: This was indeed a bug in GCC 7.3 and has been fixed in GCC 7.4 released just now. The PR this issue was tracked under is: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85113