-1

The main difference between ++var and var++ is obvious [link].

My question is about their impact on references. Here is the detail: I have a reference to a cuDF::multimap which is shown in what follows:

found = map->find(key)

When I try to increment that reference, using ++found works fine. However, using found++ returns this warning:

warning: returning reference to local variable

I understand the meaning of the warning. Can someone explain why I get this warning?

More Details

That is, the following code snippet will generate the aforementioned warning.

found = map->find(key);
while (found != map->end() && found->first != unusedKey) {
    std::cout << found->second << std::endl;
    found++;
}

However, this doesn't produce any warning:

found = map->find(key);
while (found != map->end() && found->first != unusedKey) {
    std::cout << found->second << std::endl;
    ++found;
}
MTMD
  • 1,162
  • 2
  • 11
  • 23
  • 3
    I would trust compiler that you get the warning because you are returning reference to function-local variable. – Öö Tiib Aug 19 '19 at 05:36
  • Changing `found++` to `++found` completely addresses the issue tho. – MTMD Aug 19 '19 at 05:37
  • 6
    `++found` may return the reference after inc. `found++` has to return the value before inc. Hence, you probably got a copy - a temporary. Returning the reference to it makes the compiler complaint reasonable. Btw. from your exposed code, the relevant details of `found++` are not clear. A [mcve] would be nice. – Scheff's Cat Aug 19 '19 at 05:40
  • Even though not in the accepted one, your linked question has the answer. Search for word "temporary" in browser. E.g. https://stackoverflow.com/a/1813036/5945883 https://stackoverflow.com/a/1813008/5945883 – R2RT Aug 19 '19 at 05:40
  • Btw. I doubt that `++found = map->find(key);` provides the intended result but `++(found = map->find(key));` might as well as `found = map->find(key); ++found;`. Just a thought... – Scheff's Cat Aug 19 '19 at 05:43
  • 3
    "When I try to increment that reference" Don't tell, *show*. – n. m. could be an AI Aug 19 '19 at 05:43
  • 1
    What's cuDF::multimap? – Michael Mahn Aug 19 '19 at 05:43
  • @MichaelMahn it's GPU-based multimap. Here is the link if you would like to see more: https://github.com/rapidsai/cudf. – MTMD Aug 19 '19 at 05:49
  • @n.m Thank you for your comment. Post updated accordingly. – MTMD Aug 19 '19 at 05:55
  • @R2RT Thank you very much. That answers my question. – MTMD Aug 19 '19 at 05:56
  • 1
    @all, does anyone have any idea why I got two -1 here? – MTMD Aug 19 '19 at 05:57
  • @MTMD I've downvoted you, because you're asking about the behaviour of a specific class in a third party library (namespace cuDF) without providing us with any reference to it. I know that you've posted a link to the github repository now, but not even to the file with the class which gives the warning. I just don't think that we should be expected to dig through that repository and find that class if you are the one who needs help. Sorry, I don't mean that personally and just as a hint, that you should try to ask clear questions with all information in the future. I removed my downvote now. – Michael Mahn Aug 19 '19 at 06:15
  • 1
    You need to produce a [mcve], not am out-of-context fragment. Where in the world `returning reference to local variable` could possibly happen in your fragment that has no functions and no `return` statements? – n. m. could be an AI Aug 19 '19 at 06:28

1 Answers1

6

Ok, have dived into the source code of the library cuDF.

map->find(key) returns an iterator, which is some instantiation of the template class cycle_iterator_adapter.

It has its suffix increment operator defined as follow:

__host__ __device__ cycle_iterator_adapter& operator++(int)
{
    cycle_iterator_adapter<iterator_type> old( m_begin, m_end, m_current);
    if ( m_end == (m_current+1) )
        m_current = m_begin;
    else
        ++m_current;
    return old;
}

Here the return type is cycle_iterator_adapter&, which is a reference. And since old is a local variable, returning it by reference generates the warning you see.

ph3rin
  • 4,426
  • 1
  • 18
  • 42
  • 2
    It's unfortunate when a library uses non-idiomatic code to implement fundamental pieces of their code. – R Sahu Aug 19 '19 at 06:11
  • 2
    @RSahu Yes. I believe it is a bug in the library. The operator should return `cycle_iterator_adapter` instead. – ph3rin Aug 19 '19 at 06:13