Channels ▼

Matthew Wilson

Dr. Dobb's Bloggers

(Still) be explicit to avoid those array/pointer decay ambiguities

February 06, 2010

I'm multitasking between three clients at the moment, two of whose projects are based primarily around C++. It's interesting seeing the differences between all the languages, programming styles, and tools, involved. For a consultant - horrid word - it's a refreshing and enlightening experience.

Although there is a C standard and a C++ standard, there are also different degrees of support for the standards by different compilers, not to mention some subtle (and some not-so-subtle) extensions and non-standard features. Consequently, there are myriad ways in which competent programmers can find themselves mired in incompatibilities. And that can even happen when they're adhering to the standard(s)!

Back in 2004, in my book Imperfect C++, I discussed the problems that arise from C/C++'s array-pointer duality (recently raised again by Walter Bright in this arena), and offered advice on techniques for preventing or avoiding it. For example, if you want to write (generic) code that works with a pointer as well as it does with an instance of std::vector (or any other type providing contiguous storage and a subscript operator), you should not rely on the decay of the array into a pointer:

 int              ar[10]; <br /> std::vector<int> v; <br /> int*             p; <br /> <br /> p = ar;     // 1. ok <br /> p = v;      // 2. compile error 

but rather take a pointer explicitly via the address-of and subscript operators:

 p = &ar[0]; // 3. ok <br /> p = &v[0];  // 4. ok (as long as !v.empty()) 

Hard as it is for me to imagine or accept, it seems that not everyone's read it yet, and some of the advice therein has failed to percolate as far as (I think) it should have.

We're running into such an issue in one of the commercial projects I'm currently involved with. The extant code, written for/with GCC, makes use of C99's (standard) Variable Length Arrays. Unfortunately, these are not wholly supported by all the compilers to which we're porting the codebase. This (and a bunch of other good reasons why VLA's are not suitable for use in C++) require that we substitute a more portable alternative: I advised STLSoft's auto_buffer class template, which represents a better choice for VLAs for C++.

Had the code been written with the explicit subscript/address-of operators, the change would have involved only a single line. However, the code relies on VLAs' implicit decay-to-pointer, and pointers to the array are achieved by the implicit syntax (1). So, in order to provide a clear path in the source code management's history, we're taking two passes at the code: the first pass to change implicit syntax to explicit, the second (and now simple) pass to change the array types.


Afterword:

Interesting, the syntax for real arrays has another valid form (the reasons for which are discussed in Peter van der Linden's excellent Deep C Secrets):

 p = &0[ar]; // 3. ok <br /> p = &0[v];  // 4. compile error 

This can be put to good use in applying constraints to, and discriminating between, arrays and (instances of) user-defined types, but the explanations are too lengthy for this forum; feel free to get the book and see for yourself.

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.
 


Video