Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Logically Shallow Views


May, 2005: Logically Shallow Views

Herb Sutter (http://www.gotw.ca/) chairs the ISO C++ Standards committee and is an architect in Microsoft's Developer Division. His most recent books are Exceptional C++ Style and C++ Coding Standards (Addison-Wesley). Jim Hyslop is a senior software designer for Leitch Technology International. He can be reached at jhyslop@ ieee.org.


"Hey, kid," Bob greeted me, and took a sip from his cup. "Wassup?" "Oh, hi, Bob." The microwave beeped and I took my lunch out and started eating it standing up. "Nothing much, pretty quiet day. You?"

"Same, same," he said quietly, distractedly. I wondered; that was quite unlike Bob. "It's just..."

"Yes?" I munched.

He hesitated, then said: "Well, kiddo, I guess you'd understand. Her Highness has been all over me for a while about the const thing, and even though she hasn't bugged me lately I figured maybe it'd be a good idea for me to use it in my new module..."

I was temporarily stunned. Bob, interested in const-correctness? Then I remembered to resume chewing. I don't think he noticed.

"...but it didn't work out. I did everything her One True Way, y'know, and all, not a const_cast in sight, but..."

I think my jaw actually dropped, though I managed not to lose any food. Bob, interested in const-correctness, and intentionally avoiding using hacky code?

"...even so the value changes on me, I don't know why because it sh—Hey," he frowned, "you okay?"

"I, uh, er," I stammered intelligently, but the truth was that I was so shocked at hearing Bob talk this way that it was still taking me time to adjust. I pointed at my food. "Sorry, I think I, um, swallowed this wrong. Hot. Hot" I fanned at my mouth. "Whoo."

Bob eyed me skeptically. "Anyway," he said, "I was wondering if you'd have a sec to take a quick look at my code."

At this, I nearly choked for real, but managed a nod. "Aaaah, sure." As we walked over to Bob's office, his latte sloshed in his cup and a little went over the side. I was somewhat reassured by this detail—at least it proved that I probably hadn't completely left my normal universe.

Bob pulled up his code, which looked something like this (though I'm making up the names):

class Bob {
public:
  Bob( const Other& o ) : other(o) { }
  void Cat() {
   // do some work, which includes    
   // calling const functions on "other"
  }
   // other functions
private:
  const Other& other;
};

After looking at this code and looking also into all the other functions of his class, I finally stood back and scratched my head. "Well, that all looks okay," I said. "Just like you said, not a const_cast anywhere. You said the object is somehow getting changed?"

"Right. Here, look." He stabbed a stubby finger at the contents of Bob::Cat, and left a grease spot on the screen. "Right there, I'll set a breakpoint. Watch." He ran his program, and we stopped on each entry to Bob::Cat. Sure enough, the other object's state stayed the same for a time, then inexplicably changed.

"Hunh," I hunhed. "Well, the other object always stays the same through the whole execution of your function. That's something, at least, and that's right because you aren't changing it somehow. So it has to be getting changed between calls to your function."

"Which means it's getting changed by someone else." Bob got it. "But it's const!"

Then the penny dropped, and I saw what was the matter with Bob's expectations. "Ah, I see. Sure, it's const...to you. The promise is that your view of the object is logically const. Absent casting, you promise not to change the object through this view of the object. But someone else could change it, through another reference to the object that doesn't promise const. Say..."

"What?"

"...Who's calling this code?"

"Dunno. Let me look at the stack trace..."

We looked at the screen, then at each other, and then in unison called: "Kerry!"

Seconds later, a blinking intern came around the corner. "Uh, yes sirs?" Kerry said expectantly.

We smiled and got him a seat near the screen, and Bob brought up Kerry's code:

class Kerry {
  Kerry() : bobber( myOther ) { }
  void On() {
    // ...
    myOther.Mutate();
    // ...
  }
private:
  Other myOther;
  Bob bobber;
};

"Aha!" said Bob. "There's your problem. You're passing me a non-const object, and I expected a const one."

"Aha yourself," I blurted, then blushed when I realized I'd said it aloud, but continued: "That's not what const is about. You can pass a non-const object to a function taking it via a pointer or reference to const. That just means the callee says he won't change it on you, at least not if he's playing by the rules. The two pieces of code are viewing the same object, just one promises not to use his view to change it somehow. Of course, shared state is evil in general because you'll get surprises if you don't expect extra updates to the shared object, and this is just a small sample of that. Besides..."

Snap! We jumped, as always, and found the Guru standing behind us with Wendy beside her. She handed Wendy the tome she had just snapped shut, and steepled her fingers.

"My acolyte, my apprentice," she greeted us. "Young Kerry has done well. Consider: He has even ensured that the Other object passed to Bob has a lifetime longer than Bob's."

I thought I heard Wendy add under her breath: "Like many employees in this company..."

"And," the Guru continued as though she hadn't heard, "even then the state of the object can change because const is logical—"

"Look, your Highness, I wasn't born yesterday," Bob grumbled. "I know about mutable members and how const is just a logically const thing and stuff."

"—and shallow," the Guru finished.

"Shallow?"

"Shallow how?" Kerry piped up.

"Consider this parable." The Guru picked up the whiteboard marker and wrote:

map<string, string> phoneBook;

"This maps a string name to a string phone-number name. What is the type of the contained elements?...Apprentice?" she indicated Wendy.

"It's pair<const string, string>."

"Indeed. Whether the keys of sets and maps should be mutable was a subject of some debate. The decision was that they should not be mutated. But, more than that, objects used as keys of collections may not use mutable or external state to determine their equality. Consider this..." And she wrote:

map<File, string> fileInfo;

"Here the contained element type is pair<const File, string>. What happens," she asked, "if File encapsulates a file and its comparison operators pathologically compared the actual file contents on disk?"

"Ah," I said, "I see. If the file contents change on disk, the File object hasn't changed and is still const, but now compares differently. That could break the map's sort order."

"Indeed. Though this be pathological, the same is true of any mutable state. Comparison of objects used as map or set keys should not access mutable state."

"That's pretty lame," Bob interjected. "Who would ever write code like that?"

Kerry looked bashful and slowly put up his hand. Bob snorted. "Uh, no really," Kerry stood his ground. "I wrote my QueryView class. My QueryView objects can be const and still share a mutable Query object containing refreshable query results."

"Never mind," Wendy blew it aside. "Just think of this case." And she wrote:

const smart_ptr<int> p = new int(0);
*p = 42; // ok

"See, const is shallow," she said, putting down the marker. "The pointer is const, and I'm not changing it...but I'm reaching through it to change something else. The smart pointer's operator* and operator-> don't change the pointer, so they should be const, but they can give me back something non-const. Perfectly legit, buster ol' buddy."

"So const just applies to my view of the object," I summarized aloud to myself. "And it's logical, because mutable or external state could still change through it. And it's shallow, because I can reach through a const object and change other non-const objects, without any kind of cast required. Right?"

"Indeed," the Guru said.

"Yeah, I guess," Bob muttered gruffly around his latte cup.

"Yes, Sir," Kerry agreed.

"Yup," nodded Wendy.

"Then I'd say," I quipped, "that that's a logically shallow view of const."

Several people groaned. The Guru turned to glide away, then paused long enough to throw a frown in my direction and shake her head in disgust, and then disappeared down the hallway.

Chuckling softly, I think.

Acknowledgments

Thanks to Hubert Matthews for suggesting this topic.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.