Sunday, October 7, 2012

Convoluted Const Expressions

A past manager of mine once asked me an interview question, for fun. He asked me to describe the type of something like the following:


Boy, am I glad I already had the job! I was totally lost, and at the time, I only vaguely understood his explanation of what it all meant. Of course, it always helps to have a compiler around to fiddle with.

After what we've been covering in OOP class, however, I thought I would have another shot at understanding this cryptic statement.

Not surprisingly, Wikipedia has a wealth of knowledge on the topic. I highly recommend reading through it if you're curious. It discusses how types and pointers are made immutable in several languages.

I also found a more "human" explanation. It's a bit less organized, but you also may find this to be a useful explanation.

Const Data Types



So with that preamble out of the way, let's get down to it.

Here's a brief sample, adapted from the blog entry I linked above.


I only want to explain the syntax, below, but these lines are part of a complete file (const.cpp), which shows these types in action. You can compile it and see for yourself.

Here's the intuitive way of looking at the types above:

You can split the whole type statement into two parts.
(1) the part before the star
(2) the part after (and including) the star

If the const is before the star, then it means that the data is constant. If you have a normal type, you cannot alter the data (making it a constant!). If you have a pointer or reference*, you cannot alter the data it points to.

If the const is after the star, it means the pointer is immutable -- you cannot change the address it points to. This means that the pointer is always bound to the same memory address, and you cannot change it, similar in effect to how a reference is always bound to the same location in memory.

* In the case of references, just use the ampersand as the delimiter instead of the star and the same discussion applies. However, placing the const after the ampersand is redundant because you cannot reassign a reference anyway.

I highly recommend playing with the code I linked above (const.cpp) to get a feel for what's going on.

The Interview Question



So with that information in mind, I'd like to revisit the interview question. Here is the question again, for reference: "Describe the type of 'ptr' in the following expression:"


We don't quite understand the syntax well enough yet to really answer this question, so let's take it back to const syntax and note a pattern.

When declaring a pointer (rather than its data) as const, you place the const after the star that it refers to. So if that's true, then why don't we also put const after the data type?

Well, actually, you can. These two variables have the same type:


The const keyword can always follow the type it refers to. For pointers, that's the only way you can do it. For the data type you have the option of putting it before or after. Putting it before helps with readability, so that is the preferred style.

Putting it together: a and b have the same type in the code below. c is illegal.


Armed with the new knowledge, let's revisit that interview question:


The last two lines above have the same type and point to n. We were given a, but b might be easier to figure out.

Reading from right to left: we have a pointer to an immutable pointer to an immutable int.

Some popular wrong answers my manager would get include:
1. Constant pointer to a pointer to a constant int.
2. Can you even do that?

#2: Yes you can!

And to be clear, if you wanted to get #1, you could write:



Awesome!

No comments:

Post a Comment