Opened 10 years ago

Closed 8 years ago

#7577 closed Bugs (fixed)

base_from_member with reference types

Reported by: K-ballo <kaballo86@…> Owned by: viboes
Milestone: To Be Determined Component: utility
Version: Boost 1.52.0 Severity: Problem
Keywords: Cc: Andrey.Semashev@…

Description

base_from_member constructors take their arguments by value, which causes undefined behavior if the member type is a reference, as a dangling reference is created (unless, I presume, its initialized with boost::ref/cref).

The attached patch adds a partial specialization of base_from_member for references. It provides a single constructor that takes its argument by reference.

Attachments (2)

base_from_member.patch (767 bytes ) - added by K-ballo <kaballo86@…> 10 years ago.
Fix
ref_member_from_base.cpp (1.4 KB ) - added by kaballo86@… 10 years ago.
reference base_from_member issue sample

Download all attachments as: .zip

Change History (16)

by K-ballo <kaballo86@…>, 10 years ago

Attachment: base_from_member.patch added

Fix

comment:1 by viboes, 10 years ago

Owner: changed from No-Maintainer to viboes
Status: newassigned

Could you show a use case for a base_from_member with a reference and the generated error?

by kaballo86@…, 10 years ago

Attachment: ref_member_from_base.cpp added

reference base_from_member issue sample

comment:2 by kaballo86@…, 10 years ago

I have added an use case with a reference base_from_member resulting in undefined behavior. It's based on my original use case, where I had a view over a pair of iterators and I wanted to implement a view over a container reusing the previous view. When base_from_member is instantiated with a reference, the reference points to the copy of the argument used in its construction, so it effectively becomes a dangling reference.

comment:3 by viboes, 10 years ago

Initially I didn't see the need to use base_from_member with a reference, as the referenced object is already initialized. IIUC you want that your class container_something should be able to be instantiated either with a Container and then copy it, or with a Container& and then store the reference. I find this usage a little bit bizarre. Could you tell me in which cases do you use Container and when you use Container&?

comment:4 by kaballo86@…, 10 years ago

I could tell you more about the specific use cases, but I think you are missing the point. When instantiating a base_from_member with a reference type the member will contain a dangling reference. There is no error, no warning, no assertion; only a crash at runtime if you are lucky enough.

A reference base_from_member cannot be properly initialized (I even failed to get it working by using boost::ref/cref). If my fix is rejected, then at least there should be an assert or a big bold note in base_from_member documentation saying that base_from_member cannot be used with reference types. That is unless you could tell me how would I properly initialize a base_from_member instantiated with a reference type.

in reply to:  4 comment:5 by viboes, 10 years ago

Replying to kaballo86@…:

I could tell you more about the specific use cases, but I think you are missing the point. When instantiating a base_from_member with a reference type the member will contain a dangling reference. There is no error, no warning, no assertion; only a crash at runtime if you are lucky enough.

No I didn't missed the point.

A reference base_from_member cannot be properly initialized (I even failed to get it working by using boost::ref/cref). If my fix is rejected, then at least there should be an assert or a big bold note in base_from_member documentation saying that base_from_member cannot be used with reference types. That is unless you could tell me how would I properly initialize a base_from_member instantiated with a reference type.

I understand the problem and how your patch solves the issue.

Note that I'm not against your patch, I was just curious to know when you use one or the other.

comment:6 by anonymous, 10 years ago

Ok, I was just making sure you didn't miss the actual issue with base_from_member.

The reason the member may be either a reference or a copy is simple. The class is a view, which means most of the time it will contain a reference to the actual type is adapting. However, a view could also be adapting another view, and in those cases it should contain a copy to the view rather than forcing the user to define additional named variables for the intermediate views. Then one can chain views the obvious way.

in reply to:  6 ; comment:7 by viboes, 10 years ago

Replying to anonymous:

Ok, I was just making sure you didn't miss the actual issue with base_from_member.

The reason the member may be either a reference or a copy is simple. The class is a view, which means most of the time it will contain a reference to the actual type is adapting. However, a view could also be adapting another view, and in those cases it should contain a copy to the view rather than forcing the user to define additional named variables for the intermediate views. Then one can chain views the obvious way.

Why it needs to copy the view? A concrete example will help.

in reply to:  7 comment:8 by kaballo86@…, 10 years ago

Replying to viboes:

Why it needs to copy the view? A concrete example will help.

Because that's the way it's usually done: views are copied. Views don't own their elements, in a way they are already references. Also, this allows chaining views, for instance one_view( another_view( some_container ) ) where the intermediate temporary view cannot be taken by reference.

This is totally unrelated to the issue with base_from_member, and as such I think it is off-topic. If you want to continue this discussion contact me to my email address, which you should be able to see here.

comment:9 by viboes, 10 years ago

Please, could you provide a patch for the documentation?

comment:10 by K-ballo <kaballo86@…>, 10 years ago

I can certainly try. Should that be documentation stating the issue as it stands today, or a reference for the specialization provided by my patch?

in reply to:  10 comment:11 by viboes, 9 years ago

Replying to K-ballo <kaballo86@…>:

I can certainly try. Should that be documentation stating the issue as it stands today, or a reference for the specialization provided by my patch?

The specialization provided by the patch.

comment:13 by Andrey Semashev, 8 years ago

Cc: Andrey.Semashev@… added

comment:14 by Andrey Semashev, 8 years ago

Resolution: fixed
Status: assignedclosed
Note: See TracTickets for help on using tickets.